diff --git a/android/app/build.gradle b/android/app/build.gradle index 26a2484d..96428f49 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -54,6 +54,11 @@ android { signingConfig signingConfigs.debug } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } flutter { @@ -65,6 +70,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' @@ -74,9 +80,10 @@ dependencies { //permissions implementation 'pub.devrel:easypermissions:0.4.0' //retrofit - implementation 'com.squareup.retrofit2:retrofit:2.6.2' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' - implementation 'com.squareup.okhttp3:logging-interceptor:3.14.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c656ebbf..bf0d3766 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,18 +9,24 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - - - + + + + + + + + + + - ("kApiKey") - val sessionId = call.argument("kSessionId") - val token = call.argument("kToken") - val appLang = call.argument("appLang") - val baseUrl = call.argument("baseUrl") + when (call.method) { + "openVideoCall" -> { + val apiKey = call.argument("kApiKey") + val sessionId = call.argument("kSessionId") + val token = call.argument("kToken") + val appLang = call.argument("appLang") + val baseUrl = call.argument("baseUrl") + + // Session Status model + val VC_ID = call.argument("VC_ID") + val tokenID = call.argument("TokenID") + val generalId = call.argument("generalId") + val doctorId = call.argument("DoctorId") + val patientName = call.argument("patientName") - // Session Status model - val VC_ID = call.argument("VC_ID") - val tokenID = call.argument("TokenID") - val generalId = call.argument("generalId") - val doctorId = call.argument("DoctorId") + val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId, patientName) - val sessionStatusModel = GetSessionStatusModel(VC_ID, tokenID, generalId, doctorId) + openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) - openVideoCall(apiKey, sessionId, token, appLang, baseUrl, sessionStatusModel) + } + "closeVideoCall" -> { + dialogFragment?.onCallClicked() + } + "onCallConnected" -> { - } else { - result.notImplemented() + } + else -> { + result.notImplemented() + } } } private fun openVideoCall(apiKey: String?, sessionId: String?, token: String?, appLang: String?, baseUrl: String?, sessionStatusModel: GetSessionStatusModel) { - // val videoCallActivity = VideoCallActivity() + if (dialogFragment == null) { + val arguments = Bundle() + arguments.putString("apiKey", apiKey) + arguments.putString("sessionId", sessionId) + arguments.putString("token", token) + arguments.putString("appLang", appLang) + arguments.putString("baseUrl", baseUrl) + arguments.putParcelable("sessionStatusModel", sessionStatusModel) + + val transaction = supportFragmentManager.beginTransaction() + dialogFragment = VideoCallFragment.newInstance(arguments) + dialogFragment?.let { + it.setCallListener(this) + it.isCancelable = true + if (it.isAdded){ + it.dismiss() + }else { + it.show(transaction, "dialog") + } - val intent = Intent(this, VideoCallActivity::class.java) - intent.putExtra("apiKey", apiKey) - intent.putExtra("sessionId", sessionId) - intent.putExtra("token", token) - intent.putExtra("appLang", appLang) - intent.putExtra("baseUrl", baseUrl) - intent.putExtra("sessionStatusModel", sessionStatusModel) - startActivityForResult(intent, LAUNCH_VIDEO) + } + } else if (!dialogFragment!!.isVisible) { + val transaction = supportFragmentManager.beginTransaction() + dialogFragment!!.show(transaction, "dialog") + } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - var asd = ""; - if (requestCode == LAUNCH_VIDEO) { - if (resultCode == Activity.RESULT_OK) { - val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") - val callResponse : HashMap = HashMap() + /* override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + var asd = ""; + if (requestCode == LAUNCH_VIDEO) { + if (resultCode == Activity.RESULT_OK) { + val result : SessionStatusModel? = data?.getParcelableExtra("sessionStatusNotRespond") + val callResponse : HashMap = HashMap() + + val sessionStatus : HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() - val sessionStatus : HashMap = HashMap() - val gson = GsonBuilder().serializeNulls().create() + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes - callResponse["callResponse"] = "CallNotRespond" - val jsonRes = gson.toJson(result) - callResponse["sessionStatus"] = jsonRes + this.result?.success(callResponse) + } + if (resultCode == Activity.RESULT_CANCELED) { + val callResponse : HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + result?.success(callResponse) + } + } + }*/ + + override fun onCallFinished(resultCode: Int, intent: Intent?) { + dialogFragment = null + + if (resultCode == Activity.RESULT_OK) { + val result: SessionStatusModel? = intent?.getParcelableExtra("sessionStatusNotRespond") + val callResponse: HashMap = HashMap() + + val sessionStatus: HashMap = HashMap() + val gson = GsonBuilder().serializeNulls().create() + + callResponse["callResponse"] = "CallNotRespond" + val jsonRes = gson.toJson(result) + callResponse["sessionStatus"] = jsonRes + + try { this.result?.success(callResponse) + } catch (e : Exception){ + Log.e("onVideoCallFinished", "${e.message}.") } - if (resultCode == Activity.RESULT_CANCELED) { - val callResponse : HashMap = HashMap() - callResponse["callResponse"] = "CallEnd" - + } else if (resultCode == Activity.RESULT_CANCELED) { + val callResponse: HashMap = HashMap() + callResponse["callResponse"] = "CallEnd" + try { result?.success(callResponse) + } catch (e : Exception){ + Log.e("onVideoCallFinished", "${e.message}.") } } } + override fun errorHandle(message: String) { + dialogFragment = null +// Toast.makeText(this, message, Toast.LENGTH_LONG).show() + } + + override fun minimizeVideoEvent(isMinimize: Boolean) { + if (isMinimize) + methodChannel.invokeMethod("onCallConnected", null) + else + methodChannel.invokeMethod("onCallDisconnected", null) + } + + override fun onBackPressed() { + super.onBackPressed() + } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java index d41aa146..60350539 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Model/GetSessionStatusModel.java @@ -20,15 +20,19 @@ public class GetSessionStatusModel implements Parcelable { @SerializedName("DoctorId") @Expose private Integer doctorId; + @SerializedName("PatientName") + @Expose + private String patientName; public GetSessionStatusModel() { } - public GetSessionStatusModel(Integer vCID, String tokenID, String generalid, Integer doctorId) { + public GetSessionStatusModel(Integer vCID, String tokenID, String generalid, Integer doctorId, String patientName) { this.vCID = vCID; this.tokenID = tokenID; this.generalid = generalid; this.doctorId = doctorId; + this.patientName = patientName; } protected GetSessionStatusModel(Parcel in) { @@ -44,6 +48,7 @@ public class GetSessionStatusModel implements Parcelable { } else { doctorId = in.readInt(); } + patientName = in.readString(); } public static final Creator CREATOR = new Creator() { @@ -90,6 +95,16 @@ public class GetSessionStatusModel implements Parcelable { this.doctorId = doctorId; } + public String getPatientName() { + if (patientName == null) + patientName = "-"; + return patientName; + } + + public void setPatientName(String patientName) { + this.patientName = patientName; + } + @Override public int describeContents() { return 0; @@ -111,5 +126,6 @@ public class GetSessionStatusModel implements Parcelable { dest.writeByte((byte) 1); dest.writeInt(doctorId); } + dest.writeString(patientName); } } diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java deleted file mode 100644 index 1c907089..00000000 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallActivity.java +++ /dev/null @@ -1,442 +0,0 @@ -package com.hmg.hmgDr.ui; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.opengl.GLSurfaceView; -import android.os.Bundle; -import android.os.CountDownTimer; -import android.os.Handler; -import android.util.Log; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel; -import com.hmg.hmgDr.Model.GetSessionStatusModel; -import com.hmg.hmgDr.Model.SessionStatusModel; -import com.hmg.hmgDr.R; -import com.opentok.android.Session; -import com.opentok.android.Stream; -import com.opentok.android.Publisher; -import com.opentok.android.PublisherKit; -import com.opentok.android.Subscriber; -import com.opentok.android.BaseVideoRenderer; -import com.opentok.android.OpentokError; -import com.opentok.android.SubscriberKit; - -import java.util.List; -import java.util.Objects; - -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -public class VideoCallActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks, - Session.SessionListener, - Publisher.PublisherListener, - Subscriber.VideoListener, VideoCallContract.VideoCallView { - - private static final String TAG = VideoCallActivity.class.getSimpleName(); - - VideoCallContract.VideoCallPresenter videoCallPresenter; - - private static final int RC_SETTINGS_SCREEN_PERM = 123; - private static final int RC_VIDEO_APP_PERM = 124; - - - private Session mSession; - private Publisher mPublisher; - private Subscriber mSubscriber; - - private Handler mVolHandler, mConnectedHandler; - private Runnable mVolRunnable, mConnectedRunnable; - - private FrameLayout mPublisherViewContainer; - private RelativeLayout mSubscriberViewContainer; - private RelativeLayout controlPanel; - - private String apiKey; - private String sessionId; - private String token; - private String appLang; - private String baseUrl; - - private boolean isSwitchCameraClicked; - private boolean isCameraClicked; - private boolean isSpeckerClicked; - private boolean isMicClicked; - - private ImageView mCallBtn; - private ImageView mCameraBtn; - private ImageView mSwitchCameraBtn; - private ImageView mspeckerBtn; - private ImageView mMicBtn; - - private ProgressBar progressBar; - private CountDownTimer countDownTimer; - private TextView progressBarTextView; - private RelativeLayout progressBarLayout; - - private boolean isConnected = false; - - private GetSessionStatusModel sessionStatusModel; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - setTheme(R.style.AppTheme); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_video_call); - Objects.requireNonNull(getSupportActionBar()).hide(); - initUI(); - requestPermissions(); - } - - @Override - protected void onPause() { - super.onPause(); - - if (mSession == null) { - return; - } - mSession.onPause(); - - if (isFinishing()) { - disconnectSession(); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (mSession == null) { - return; - } - mSession.onResume(); - } - - @Override - protected void onDestroy() { - disconnectSession(); - - super.onDestroy(); - } - - @SuppressLint("ClickableViewAccessibility") - private void initUI() { - mPublisherViewContainer = (FrameLayout) findViewById(R.id.local_video_view_container); - mSubscriberViewContainer = (RelativeLayout) findViewById(R.id.remote_video_view_container); - - apiKey = getIntent().getStringExtra("apiKey"); - sessionId = getIntent().getStringExtra("sessionId"); - token = getIntent().getStringExtra("token"); - appLang = getIntent().getStringExtra("appLang"); - baseUrl = getIntent().getStringExtra("baseUrl"); - sessionStatusModel = getIntent().getParcelableExtra("sessionStatusModel"); - - controlPanel = findViewById(R.id.control_panel); - - videoCallPresenter = new VideoCallPresenterImpl(this, baseUrl); - - - mCallBtn = findViewById(R.id.btn_call); - mCameraBtn = findViewById(R.id.btn_camera); - mSwitchCameraBtn = findViewById(R.id.btn_switch_camera); - mspeckerBtn = findViewById(R.id.btn_specker); - mMicBtn = findViewById(R.id.btn_mic); - - // progressBarLayout=findViewById(R.id.progressBar); - // progressBar=findViewById(R.id.progress_bar); -// progressBarTextView=findViewById(R.id.progress_bar_text); -// progressBar.setVisibility(View.GONE); - - hiddenButtons(); - - checkClientConnected(); - - mSubscriberViewContainer.setOnTouchListener((v, event) -> { - controlPanel.setVisibility(View.VISIBLE); - mVolHandler.removeCallbacks(mVolRunnable); - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - return true; - }); - - if (appLang.equals("ar")) { - progressBarLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); - } - - } - - private void checkClientConnected() { - mConnectedHandler = new Handler(); - mConnectedRunnable = () -> { - if (!isConnected) { - videoCallPresenter.callClintConnected(sessionStatusModel); - } - }; - mConnectedHandler.postDelayed(mConnectedRunnable, 30 * 1000); - - } - - private void hiddenButtons() { - mVolHandler = new Handler(); - mVolRunnable = new Runnable() { - public void run() { - controlPanel.setVisibility(View.GONE); - } - }; - mVolHandler.postDelayed(mVolRunnable, 5 * 1000); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - - @Override - public void onPermissionsGranted(int requestCode, List perms) { - Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size()); - } - - @Override - public void onPermissionsDenied(int requestCode, List perms) { - Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); - - if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { - new AppSettingsDialog.Builder(this) - .setTitle(getString(R.string.title_settings_dialog)) - .setRationale(getString(R.string.rationale_ask_again)) - .setPositiveButton(getString(R.string.setting)) - .setNegativeButton(getString(R.string.cancel)) - .setRequestCode(RC_SETTINGS_SCREEN_PERM) - .build() - .show(); - } - } - - @AfterPermissionGranted(RC_VIDEO_APP_PERM) - private void requestPermissions() { - String[] perms = {Manifest.permission.INTERNET, Manifest.permission.CAMERA,}; - if (EasyPermissions.hasPermissions(this, perms)) { - try { - mSession = new Session.Builder(this, apiKey, sessionId).build(); - mSession.setSessionListener(this); - mSession.connect(token); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, perms); - } - } - - @Override - public void onConnected(Session session) { - Log.i(TAG, "Session Connected"); - - mPublisher = new Publisher.Builder(this).build(); - mPublisher.setPublisherListener(this); - - mPublisherViewContainer.addView(mPublisher.getView()); - - if (mPublisher.getView() instanceof GLSurfaceView) { - ((GLSurfaceView) mPublisher.getView()).setZOrderOnTop(true); - } - - mSession.publish(mPublisher); - } - - @Override - public void onDisconnected(Session session) { - Log.d(TAG, "onDisconnected: disconnected from session " + session.getSessionId()); - - mSession = null; - } - - @Override - public void onError(Session session, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in session " + session.getSessionId()); - - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); - } - - @Override - public void onStreamReceived(Session session, Stream stream) { - Log.d(TAG, "onStreamReceived: New stream " + stream.getStreamId() + " in session " + session.getSessionId()); - if (mSubscriber != null) { - isConnected = true; - return; - } - isConnected = true; - subscribeToStream(stream); - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(3,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - } - - @Override - public void onStreamDropped(Session session, Stream stream) { - Log.d(TAG, "onStreamDropped: Stream " + stream.getStreamId() + " dropped from session " + session.getSessionId()); - - if (mSubscriber == null) { - return; - } - - if (mSubscriber.getStream().equals(stream)) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSubscriber.destroy(); - mSubscriber = null; - } - disconnectSession(); - } - - @Override - public void onStreamCreated(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamCreated: Own stream " + stream.getStreamId() + " created"); - } - - @Override - public void onStreamDestroyed(PublisherKit publisherKit, Stream stream) { - Log.d(TAG, "onStreamDestroyed: Own stream " + stream.getStreamId() + " destroyed"); - } - - @Override - public void onError(PublisherKit publisherKit, OpentokError opentokError) { - Log.d(TAG, "onError: Error (" + opentokError.getMessage() + ") in publisher"); - - Toast.makeText(this, "Session error. See the logcat please.", Toast.LENGTH_LONG).show(); - finish(); - } - - @Override - public void onVideoDataReceived(SubscriberKit subscriberKit) { - mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL); - mSubscriberViewContainer.addView(mSubscriber.getView()); - } - - @Override - public void onVideoDisabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoEnabled(SubscriberKit subscriberKit, String s) { - - } - - @Override - public void onVideoDisableWarning(SubscriberKit subscriberKit) { - - } - - @Override - public void onVideoDisableWarningLifted(SubscriberKit subscriberKit) { - - } - - private void subscribeToStream(Stream stream) { - mSubscriber = new Subscriber.Builder(VideoCallActivity.this, stream).build(); - mSubscriber.setVideoListener(this); - mSession.subscribe(mSubscriber); - } - - private void disconnectSession() { - if (mSession == null) { - setResult(Activity.RESULT_CANCELED); - finish(); - return; - } - - if (mSubscriber != null) { - mSubscriberViewContainer.removeView(mSubscriber.getView()); - mSession.unsubscribe(mSubscriber); - mSubscriber.destroy(); - mSubscriber = null; - } - - if (mPublisher != null) { - mPublisherViewContainer.removeView(mPublisher.getView()); - mSession.unpublish(mPublisher); - mPublisher.destroy(); - mPublisher = null; - } - mSession.disconnect(); - if (countDownTimer != null) { - countDownTimer.cancel(); - } - videoCallPresenter.callChangeCallStatus(new ChangeCallStatusRequestModel(16,sessionStatusModel.getDoctorId(), sessionStatusModel.getGeneralid(),token,sessionStatusModel.getVCID())); - finish(); - } - - public void onSwitchCameraClicked(View view) { - if (mPublisher != null) { - isSwitchCameraClicked = !isSwitchCameraClicked; - mPublisher.cycleCamera(); - int res = isSwitchCameraClicked ? R.drawable.flip_disapled : R.drawable.flip_enabled; - mSwitchCameraBtn.setImageResource(res); - } - } - - public void onCameraClicked(View view) { - if (mPublisher != null) { - isCameraClicked = !isCameraClicked; - mPublisher.setPublishVideo(!isCameraClicked); - int res = isCameraClicked ? R.drawable.video_disanabled : R.drawable.video_enabled; - mCameraBtn.setImageResource(res); - } - } - - public void onSpeckerClicked(View view) { - if (mSubscriber != null) { - isSpeckerClicked = !isSpeckerClicked; - mSubscriber.setSubscribeToAudio(!isSpeckerClicked); - int res = isSpeckerClicked ? R.drawable.audio_disabled : R.drawable.audio_enabled; - mspeckerBtn.setImageResource(res); - } - } - - public void onMicClicked(View view) { - - if (mPublisher != null) { - isMicClicked = !isMicClicked; - mPublisher.setPublishAudio(!isMicClicked); - int res = isMicClicked ? R.drawable.mic_disabled : R.drawable.mic_enabled; - mMicBtn.setImageResource(res); - } - } - - public void onCallClicked(View view) { - disconnectSession(); - } - - @Override - public void onCallSuccessful(SessionStatusModel sessionStatusModel) { - if (sessionStatusModel.getSessionStatus() == 2 || sessionStatusModel.getSessionStatus() == 3) { - Intent returnIntent = new Intent(); - returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } - } - - @Override - public void onCallChangeCallStatusSuccessful(SessionStatusModel sessionStatusModel) { - - } - - @Override - public void onFailure() { - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt new file mode 100644 index 00000000..204568a4 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/VideoCallResponseListener.kt @@ -0,0 +1,14 @@ +package com.hmg.hmgDr.ui + +import android.content.Intent + +interface VideoCallResponseListener { + + fun onCallFinished(resultCode : Int, intent: Intent? = null) + + fun errorHandle(message: String) + + fun minimizeVideoEvent(isMinimize : Boolean) + + fun onBackHandle(){} +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt new file mode 100644 index 00000000..35e28b23 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/ui/fragment/VideoCallFragment.kt @@ -0,0 +1,893 @@ +package com.hmg.hmgDr.ui.fragment + +import android.Manifest +import android.annotation.SuppressLint +import android.app.Activity +import android.app.Dialog +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.graphics.Point +import android.graphics.drawable.ColorDrawable +import android.opengl.GLSurfaceView +import android.os.* +import android.util.Log +import android.view.* +import android.widget.* +import androidx.annotation.Nullable +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat +import androidx.core.view.GestureDetectorCompat +import androidx.fragment.app.DialogFragment +import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel +import com.hmg.hmgDr.Model.GetSessionStatusModel +import com.hmg.hmgDr.Model.SessionStatusModel +import com.hmg.hmgDr.R +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter +import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView +import com.hmg.hmgDr.ui.VideoCallPresenterImpl +import com.hmg.hmgDr.ui.VideoCallResponseListener +import com.hmg.hmgDr.util.DynamicVideoRenderer +import com.hmg.hmgDr.util.ThumbnailCircleVideoRenderer +import com.opentok.android.* +import com.opentok.android.PublisherKit.PublisherListener +import pub.devrel.easypermissions.AfterPermissionGranted +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions +import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks +import kotlin.math.ceil + + +class VideoCallFragment : DialogFragment(), PermissionCallbacks, Session.SessionListener, PublisherListener, + SubscriberKit.VideoListener, VideoCallView { + + private var isFullScreen: Boolean = true + private var isCircle: Boolean = false + private var x_init_cord = 0 + private var y_init_cord: Int = 0 + private var x_init_margin: Int = 0 + private var y_init_margin: Int = 0 + private val szWindow: Point = Point() + private lateinit var mWindowManager: WindowManager + private var isLeft = true + + private lateinit var videoCallPresenter: VideoCallPresenter + + private var mSession: Session? = null + private var mPublisher: Publisher? = null + private var mSubscriber: Subscriber? = null + + private var mVolHandler: Handler? = null + private var mConnectedHandler: Handler? = null + private var mVolRunnable: Runnable? = null + private var mConnectedRunnable: Runnable? = null + + private lateinit var thumbnail_container: FrameLayout + private lateinit var mPublisherViewContainer: FrameLayout + private lateinit var mPublisherViewIcon: View + private lateinit var mSubscriberViewContainer: FrameLayout + private lateinit var mSubscriberViewIcon: ImageView + private lateinit var controlPanel: ConstraintLayout + + private var apiKey: String? = null + private var sessionId: String? = null + private var token: String? = null + private var appLang: String? = null + private var baseUrl: String? = null + + private var isSwitchCameraClicked = false + private var isCameraClicked = false + private var isSpeckerClicked = false + private var isMicClicked = false + + private lateinit var parentView: View + private lateinit var videoCallContainer: ConstraintLayout + private lateinit var layoutName: RelativeLayout + private lateinit var layoutMini: RelativeLayout + private lateinit var icMini: ImageButton + private lateinit var mCallBtn: ImageView + private lateinit var btnMinimize: ImageView + private lateinit var mCameraBtn: ImageView + private lateinit var mSwitchCameraBtn: ImageView + private lateinit var mspeckerBtn: ImageView + private lateinit var mMicBtn: ImageView + + private lateinit var patientName: TextView + private lateinit var cmTimer: Chronometer + private var elapsedTime: Long = 0 + private var resume = false + + private val progressBar: ProgressBar? = null + private val countDownTimer: CountDownTimer? = null + private val progressBarTextView: TextView? = null + private val progressBarLayout: RelativeLayout? = null + + private var isConnected = false + + private var sessionStatusModel: GetSessionStatusModel? = null + private var videoCallResponseListener: VideoCallResponseListener? = null + private lateinit var mDetector: GestureDetectorCompat + + override fun onCreate(savedInstanceState: Bundle?) { + requireActivity().setTheme(R.style.AppTheme) + super.onCreate(savedInstanceState) + } + + override fun onStart() { + super.onStart() + + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + + override fun getTheme(): Int { + return R.style.dialogTheme + } + + override fun onCreateDialog(@Nullable savedInstanceState: Bundle?): Dialog { + val dialog: Dialog = super.onCreateDialog(savedInstanceState) + + // Add back button listener + // Add back button listener + dialog.setOnKeyListener { _, keyCode, keyEvent -> + // getAction to make sure this doesn't double fire + if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) { + videoCallResponseListener?.onBackHandle() + false // Capture onKey + } else true + // Don't capture + } + + return dialog + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // This is done in a post() since the dialog must be drawn before locating. + requireView().post { + val dialogWindow = dialog!!.window + + if (dialog != null && dialogWindow != null) { + dialogWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)); + } + + // Make the dialog possible to be outside touch + dialogWindow!!.setFlags( + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, + WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + ) + dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + requireView().invalidate() + } + } + + fun setCallListener(videoCallResponseListener: VideoCallResponseListener) { + this.videoCallResponseListener = videoCallResponseListener + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View { + + parentView = inflater.inflate(R.layout.activity_video_call, container, false) + + // Objects.requireNonNull(requireActivity().actionBar)!!.hide() + arguments?.run { + apiKey = getString("apiKey") + sessionId = getString("sessionId") + token = getString("token") + appLang = getString("appLang") + baseUrl = getString("baseUrl") + sessionStatusModel = getParcelable("sessionStatusModel") + } + initUI(parentView) + requestPermissions() + + handleDragDialog() + mDetector = GestureDetectorCompat(context, MyGestureListener({ showControlPanelTemporarily() }, { miniCircleDoubleTap() })) + + return parentView + } + + + override fun onPause() { + super.onPause() + if (mSession == null) { + return + } + mSession!!.onPause() + if (requireActivity().isFinishing) { + disconnectSession() + } + } + + override fun onResume() { + super.onResume() + if (mSession == null) { + return + } + mSession!!.onResume() + } + + override fun onDestroy() { + disconnectSession() + cmTimer.stop() + super.onDestroy() + } + + @SuppressLint("ClickableViewAccessibility") + private fun initUI(view: View) { + videoCallContainer = view.findViewById(R.id.video_call_ll) + layoutName = view.findViewById(R.id.layout_name) + layoutMini = view.findViewById(R.id.layout_mini) + icMini = view.findViewById(R.id.ic_mini) + thumbnail_container = view.findViewById(R.id.thumbnail_container) + mPublisherViewContainer = view.findViewById(R.id.local_video_view_container) + mPublisherViewIcon = view.findViewById(R.id.local_video_view_icon) + mSubscriberViewIcon = view.findViewById(R.id.remote_video_view_icon) + mSubscriberViewContainer = view.findViewById(R.id.remote_video_view_container) + + patientName = view.findViewById(R.id.patient_name) + patientName.text = sessionStatusModel!!.patientName + + cmTimer = view.findViewById(R.id.cmTimer) + cmTimer.format = "mm:ss" + cmTimer.onChronometerTickListener = Chronometer.OnChronometerTickListener { arg0: Chronometer? -> + val minutes: Long + val seconds: Long + if (!resume) { + minutes = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 / 60 + seconds = (SystemClock.elapsedRealtime() - cmTimer.base) / 1000 % 60 + elapsedTime = SystemClock.elapsedRealtime() + } else { + minutes = (elapsedTime - cmTimer.base) / 1000 / 60 + seconds = (elapsedTime - cmTimer.base) / 1000 % 60 + elapsedTime += 1000 + } + arg0?.text = "$minutes:$seconds" + Log.d(VideoCallFragment.TAG, "onChronometerTick: $minutes : $seconds") + } + + icMini.setOnClickListener { + onMiniCircleClicked() + } + + controlPanel = view.findViewById(R.id.control_panel) + videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) + mCallBtn = view.findViewById(R.id.btn_call) + mCallBtn.setOnClickListener { + onCallClicked() + } + btnMinimize = view.findViewById(R.id.btn_minimize) + btnMinimize.setOnClickListener { + onMinimizedClicked(it) + } + mCameraBtn = view.findViewById(R.id.btn_camera) + mCameraBtn.setOnClickListener { + onCameraClicked(it) + } + mSwitchCameraBtn = view.findViewById(R.id.btn_switch_camera) + mSwitchCameraBtn.setOnClickListener { + onSwitchCameraClicked(it) + } + mspeckerBtn = view.findViewById(R.id.btn_specker) + mspeckerBtn.setOnClickListener { + onSpeckerClicked(it) + } + mMicBtn = view.findViewById(R.id.btn_mic) + mMicBtn.setOnClickListener { + onMicClicked(it) + } + // progressBarLayout=findViewById(R.id.progressBar); + // progressBar=findViewById(R.id.progress_bar); +// progressBarTextView=findViewById(R.id.progress_bar_text); +// progressBar.setVisibility(View.GONE); + hiddenButtons() + checkClientConnected() + + if (appLang == "ar") { + progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL + } + } + + private fun checkClientConnected() { + mConnectedHandler = Handler((Looper.getMainLooper())) + mConnectedRunnable = Runnable { + if (!isConnected) { + videoCallPresenter.callClintConnected(sessionStatusModel) + } + } + mConnectedHandler!!.postDelayed(mConnectedRunnable!!, (55 * 1000).toLong()) + } + + private fun hiddenButtons() { + mVolHandler = Handler() + mVolRunnable = Runnable { controlPanel.visibility = View.GONE } + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun onPermissionsGranted(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size) + } + + override fun onPermissionsDenied(requestCode: Int, perms: List) { + Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size) + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + AppSettingsDialog.Builder(this) + .setTitle(getString(R.string.title_settings_dialog)) + .setRationale(getString(R.string.rationale_ask_again)) + .setPositiveButton(getString(R.string.setting)) + .setNegativeButton(getString(R.string.cancel)) + .setRequestCode(RC_SETTINGS_SCREEN_PERM) + .build() + .show() + } + } + + @AfterPermissionGranted(RC_VIDEO_APP_PERM) + private fun requestPermissions() { + val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.CALL_PHONE) + if (EasyPermissions.hasPermissions(requireContext(), *perms)) { + try { + mSession = Session.Builder(context, apiKey, sessionId).build() + mSession!!.setSessionListener(this) + mSession!!.connect(token) + } catch (e: Exception) { + e.printStackTrace() + } + } else { + EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, *perms) + } + } + + override fun onConnected(session: Session?) { + Log.i(TAG, "Session Connected") + mPublisher = Publisher.Builder(requireContext()) +// .name("publisher") +// .renderer(ThumbnailCircleVideoRenderer(requireContext())) + .build() + mPublisher!!.setPublisherListener(this) + if (mPublisher!!.view is GLSurfaceView) { + (mPublisher!!.view as GLSurfaceView).setZOrderOnTop(true) + } + + mPublisherViewContainer.addView(mPublisher!!.view) + mSession!!.publish(mPublisher) + + if (!resume) { + cmTimer.base = SystemClock.elapsedRealtime() + } + cmTimer.start() + videoCallResponseListener?.minimizeVideoEvent(true) + } + + override fun onDisconnected(session: Session) { + Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId) + mSession = null + cmTimer.stop() + disconnectSession() + videoCallResponseListener?.minimizeVideoEvent(false) + } + + override fun onError(session: Session, opentokError: OpentokError) { + Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId) + + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in session ") +// dialog?.dismiss() + } + + override fun onStreamReceived(session: Session, stream: Stream) { + Log.d(TAG, "onStreamReceived: New stream " + stream.streamId + " in session " + session.sessionId) + if (mSubscriber != null) { + isConnected = true + return + } + isConnected = true + subscribeToStream(stream) + if (mConnectedHandler != null && mConnectedRunnable != null) + mConnectedHandler!!.removeCallbacks(mConnectedRunnable!!) + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + } + + override fun onStreamDropped(session: Session, stream: Stream) { + Log.d(TAG, "onStreamDropped: Stream " + stream.streamId + " dropped from session " + session.sessionId) + if (mSubscriber == null) { + return + } + if (mSubscriber!!.stream == stream) { + mSubscriberViewContainer.removeView(mSubscriber!!.view) + mSubscriber!!.destroy() + mSubscriber = null + } + disconnectSession() + } + + override fun onStreamCreated(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamCreated: Own stream " + stream.streamId + " created") + } + + override fun onStreamDestroyed(publisherKit: PublisherKit?, stream: Stream) { + Log.d(TAG, "onStreamDestroyed: Own stream " + stream.streamId + " destroyed") + } + + override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) { + Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher") + // videoCallResponseListener?.errorHandle("Error (" + opentokError.message + ") in publisher") +// dialog?.dismiss() + } + + override fun onVideoDataReceived(subscriberKit: SubscriberKit?) { + mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(mSubscriber!!.view) +// switchToThumbnailCircle() + } + + fun switchToThumbnailCircle() { + thumbnail_container.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(true) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(true) + thumbnail_container.addView(view) + } + } + switchToFullScreenView() + }, 4000) + } + + fun switchToFullScreenView() { + mSubscriberViewContainer.postDelayed({ + val view = mSubscriber!!.view + if (view.parent != null) { + (view.parent as ViewGroup).removeView(view) + } + if (view is GLSurfaceView) { + view.setZOrderOnTop(false) + if (mSubscriber!!.renderer is DynamicVideoRenderer) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(false) + mSubscriberViewContainer.addView(view) + } + } + switchToThumbnailCircle() + }, 4000) + } + + override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {} + + override fun onVideoDisableWarning(subscriberKit: SubscriberKit?) {} + + override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {} + + private fun subscribeToStream(stream: Stream) { + mSubscriber = Subscriber.Builder(requireContext(), stream) + .renderer(DynamicVideoRenderer(requireContext())) + .build() + mSubscriber!!.setVideoListener(this) + mSession!!.subscribe(mSubscriber) + } + + private fun disconnectSession() { + if (mSession == null) { + videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) +// requireActivity().setResult(Activity.RESULT_CANCELED) + dialog?.dismiss() + return + } + + if (mSubscriber != null) { + mSubscriberViewContainer.removeView(mSubscriber!!.view) + mSession!!.unsubscribe(mSubscriber) + mSubscriber!!.destroy() + mSubscriber = null + } + if (mPublisher != null) { + mPublisherViewContainer.removeView(mPublisher!!.view) + mSession!!.unpublish(mPublisher) + mPublisher!!.destroy() + mPublisher = null + } + mSession!!.disconnect() + countDownTimer?.cancel() + + videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid)) + dialog?.dismiss() + } + + override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) { + if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) { + val returnIntent = Intent() + returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) + videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) +// requireActivity().setResult(Activity.RESULT_OK, returnIntent) + dialog?.dismiss() + } + } + + override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {} + + override fun onFailure() {} + + private fun onSwitchCameraClicked(view: View?) { + if (mPublisher != null) { + isSwitchCameraClicked = !isSwitchCameraClicked + mPublisher!!.cycleCamera() + val res = if (isSwitchCameraClicked) R.drawable.camera_front else R.drawable.camera_back + mSwitchCameraBtn.setImageResource(res) + } + } + + fun onCallClicked() { + disconnectSession() + } + + private fun miniCircleDoubleTap() { + if (isCircle) { + onMiniCircleClicked() + } + } + + private fun onMiniCircleClicked() { + if (isCircle) { + dialog?.window?.setLayout( + 400, + 600 + ) + } else { + dialog?.window?.setLayout( + 300, + 300 + ) + } + isCircle = !isCircle + + if (mSubscriber != null) { + (mSubscriber!!.renderer as DynamicVideoRenderer).enableThumbnailCircle(isCircle) + } else { + if (isCircle) { + videoCallContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + mSubscriberViewContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.circle_shape) + } else { + videoCallContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + mSubscriberViewContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_color)) + } + + } + + if (isCircle) { + controlPanel.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } + } + + private fun onMinimizedClicked(view: View?) { + if (isFullScreen) { + dialog?.window?.setLayout( + 400, + 600 + ) + } else { + dialog?.window?.setLayout( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + isFullScreen = !isFullScreen + + val res = if (isFullScreen) R.drawable.reducing else R.drawable.expand + btnMinimize.setImageResource(res) + setViewsVisibility() + +// videoCallResponseListener?.minimizeVideoEvent(!isFullScreen) + } + + private fun setViewsVisibility() { + val iconSize: Int = context!!.resources.getDimension(R.dimen.video_icon_size).toInt() + val iconSizeSmall: Int = context!!.resources.getDimension(R.dimen.video_icon_size_small).toInt() + val btnMinimizeLayoutParam: ConstraintLayout.LayoutParams = btnMinimize.layoutParams as ConstraintLayout.LayoutParams + val mCallBtnLayoutParam: ConstraintLayout.LayoutParams = mCallBtn.layoutParams as ConstraintLayout.LayoutParams + + val localPreviewMargin: Int = context!!.resources.getDimension(R.dimen.local_preview_margin_top).toInt() + val localPreviewWidth: Int = context!!.resources.getDimension(R.dimen.local_preview_width).toInt() + val localPreviewHeight: Int = context!!.resources.getDimension(R.dimen.local_preview_height).toInt() +// val localPreviewIconSize: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size).toInt() +// val localPreviewMarginSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_margin_small).toInt() +// val localPreviewWidthSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_width_small).toInt() +// val localPreviewHeightSmall : Int = context!!.resources.getDimension(R.dimen.local_preview_height_small).toInt() +// val localPreviewIconSmall: Int = context!!.resources.getDimension(R.dimen.local_back_icon_size_small).toInt() +// val localPreviewLayoutIconParam : FrameLayout.LayoutParams + val localPreviewLayoutParam: RelativeLayout.LayoutParams = mPublisherViewContainer.layoutParams as RelativeLayout.LayoutParams + + val remotePreviewIconSize: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size).toInt() + val remotePreviewIconSizeSmall: Int = context!!.resources.getDimension(R.dimen.remote_back_icon_size_small).toInt() + val remotePreviewLayoutParam: FrameLayout.LayoutParams = mSubscriberViewIcon.layoutParams as FrameLayout.LayoutParams + + if (isFullScreen) { + layoutName.visibility = View.VISIBLE + layoutMini.visibility = View.GONE + mCameraBtn.visibility = View.VISIBLE + mSwitchCameraBtn.visibility = View.VISIBLE +// mspeckerBtn.visibility = View.VISIBLE + mMicBtn.visibility = View.VISIBLE + + btnMinimizeLayoutParam.width = iconSize + btnMinimizeLayoutParam.height = iconSize + mCallBtnLayoutParam.width = iconSize + mCallBtnLayoutParam.height = iconSize +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSize, localPreviewIconSize) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidth, localPreviewHeight) + localPreviewLayoutParam.width = localPreviewWidth + localPreviewLayoutParam.height = localPreviewHeight + localPreviewLayoutParam.setMargins(0, localPreviewMargin, localPreviewMargin, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSize, remotePreviewIconSize) + remotePreviewLayoutParam.width = remotePreviewIconSize + remotePreviewLayoutParam.height = remotePreviewIconSize + } else { + layoutName.visibility = View.GONE + layoutMini.visibility = View.VISIBLE + mCameraBtn.visibility = View.GONE + mSwitchCameraBtn.visibility = View.GONE +// mspeckerBtn.visibility = View.GONE + mMicBtn.visibility = View.GONE +// mPublisherViewContainer.visibility = View.GONE +// mPublisherViewIcon.visibility = View.GONE + +// layoutParam = ConstraintLayout.LayoutParams(iconSizeSmall, iconSizeSmall) + btnMinimizeLayoutParam.width = iconSizeSmall + btnMinimizeLayoutParam.height = iconSizeSmall + mCallBtnLayoutParam.width = iconSizeSmall + mCallBtnLayoutParam.height = iconSizeSmall + + localPreviewLayoutParam.width = 0 + localPreviewLayoutParam.height = 0 + localPreviewLayoutParam.setMargins(0, localPreviewMargin / 2, localPreviewMargin / 2, 0) +// localPreviewLayoutIconParam = FrameLayout.LayoutParams(localPreviewIconSmall, localPreviewIconSmall) +//// localPreviewLayoutParam = RelativeLayout.LayoutParams(localPreviewWidthSmall, localPreviewHeightSmall) +// localPreviewLayoutParam.width = localPreviewWidthSmall +// localPreviewLayoutParam.height = localPreviewWidthSmall +// localPreviewLayoutParam.setMargins(0,localPreviewMarginSmall, localPreviewMarginSmall, 0) +// remotePreviewLayoutParam = FrameLayout.LayoutParams(remotePreviewIconSizeSmall, remotePreviewIconSizeSmall) + remotePreviewLayoutParam.width = remotePreviewIconSizeSmall + remotePreviewLayoutParam.height = remotePreviewIconSizeSmall + + if (isCircle) { + controlPanel.visibility = View.GONE + layoutMini.visibility = View.GONE + } else { + controlPanel.visibility = View.VISIBLE + layoutMini.visibility = View.VISIBLE + } + } + + mPublisherViewContainer.layoutParams = localPreviewLayoutParam +// mPublisherViewIcon.layoutParams = localPreviewLayoutIconParam + mSubscriberViewIcon.layoutParams = remotePreviewLayoutParam + + btnMinimize.layoutParams = btnMinimizeLayoutParam + mCallBtn.layoutParams = mCallBtnLayoutParam + } + + private fun onCameraClicked(view: View?) { + if (mPublisher != null) { + isCameraClicked = !isCameraClicked + mPublisher!!.publishVideo = !isCameraClicked + val res = if (isCameraClicked) R.drawable.video_disabled else R.drawable.video_enabled + mCameraBtn!!.setImageResource(res) + } + } + + private fun onMicClicked(view: View?) { + if (mPublisher != null) { + isMicClicked = !isMicClicked + mPublisher!!.publishAudio = !isMicClicked + val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled + mMicBtn!!.setImageResource(res) + } + } + + private fun onSpeckerClicked(view: View?) { + if (mSubscriber != null) { + isSpeckerClicked = !isSpeckerClicked + mSubscriber!!.subscribeToAudio = !isSpeckerClicked + val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled + mspeckerBtn.setImageResource(res) + } + } + + @SuppressLint("ClickableViewAccessibility") + private fun handleDragDialog() { + mWindowManager = requireActivity().getSystemService(Context.WINDOW_SERVICE) as WindowManager + getWindowManagerDefaultDisplay() + + videoCallContainer.setOnTouchListener(dragListener) + mSubscriberViewContainer.setOnTouchListener(dragListener) + } + + @SuppressLint("ClickableViewAccessibility") + private val dragListener: View.OnTouchListener = View.OnTouchListener { _, event -> + mDetector.onTouchEvent(event) + + //Get Floating widget view params + val layoutParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + //get the touch location coordinates + val x_cord = event.rawX.toInt() + val y_cord = event.rawY.toInt() + val x_cord_Destination: Int + var y_cord_Destination: Int + + when (event.action) { + MotionEvent.ACTION_DOWN -> { + x_init_cord = x_cord + y_init_cord = y_cord + + //remember the initial position. + x_init_margin = layoutParams.x + y_init_margin = layoutParams.y + } + MotionEvent.ACTION_UP -> { + //Get the difference between initial coordinate and current coordinate + val x_diff: Int = x_cord - x_init_cord + val y_diff: Int = y_cord - y_init_cord + + y_cord_Destination = y_init_margin + y_diff + val barHeight: Int = getStatusBarHeight() + if (y_cord_Destination < 0) { +// y_cord_Destination = 0 +// y_cord_Destination = +// -(szWindow.y - (videoCallContainer.height /*+ barHeight*/)) + y_cord_Destination = -(szWindow.y / 2) + } else if (y_cord_Destination + (videoCallContainer.height + barHeight) > szWindow.y) { +// y_cord_Destination = szWindow.y - (videoCallContainer.height + barHeight) + y_cord_Destination = (szWindow.y / 2) + } + layoutParams.y = y_cord_Destination + + //reset position if user drags the floating view + resetPosition(x_cord) + } + MotionEvent.ACTION_MOVE -> { + val x_diff_move: Int = x_cord - x_init_cord + val y_diff_move: Int = y_cord - y_init_cord + x_cord_Destination = x_init_margin + x_diff_move + y_cord_Destination = y_init_margin + y_diff_move + + layoutParams.x = x_cord_Destination + layoutParams.y = y_cord_Destination + + dialog!!.window!!.attributes = layoutParams + } + } + true + } + + private fun showControlPanelTemporarily() { + if (!isCircle) { + controlPanel.visibility = View.VISIBLE + mVolHandler!!.removeCallbacks(mVolRunnable!!) + mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong()) + } + } + + /* Reset position of Floating Widget view on dragging */ + private fun resetPosition(x_cord_now: Int) { + if (x_cord_now <= szWindow.x / 2) { + isLeft = true + moveToLeft(x_cord_now) + } else { + isLeft = false + moveToRight(x_cord_now) + } + } + + /* Method to move the Floating widget view to Left */ + private fun moveToLeft(current_x_cord: Int) { + + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + + mParams.x = + (szWindow.x - current_x_cord * current_x_cord - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + val x = szWindow.x - current_x_cord + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + // mParams.x = 0 - (current_x_cord * current_x_cord * step).toInt() + mParams.x = + (szWindow.x - current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } + + override fun onFinish() { + mParams.x = -(szWindow.x - videoCallContainer.width) + + dialog!!.window!!.attributes = mParams + } + }.start() + } + + /* Method to move the Floating widget view to Right */ + private fun moveToRight(current_x_cord: Int) { +// var mParams : WindowManager.LayoutParams = dialog!!.window!!.attributes +// mParams.x = +// (szWindow.x + current_x_cord * current_x_cord - videoCallContainer.width).toInt() +// +// dialog!!.window!!.attributes = mParams + object : CountDownTimer(500, 5) { + //get params of Floating Widget view + var mParams: WindowManager.LayoutParams = dialog!!.window!!.attributes + override fun onTick(t: Long) { + val step = (500 - t) / 5 + mParams.x = + (szWindow.x + current_x_cord * current_x_cord * step - videoCallContainer.width).toInt() + + dialog!!.window!!.attributes = mParams + } + + override fun onFinish() { + mParams.x = szWindow.x - videoCallContainer.width + + dialog!!.window!!.attributes = mParams + } + }.start() + } + + private fun getWindowManagerDefaultDisplay() { + mWindowManager.getDefaultDisplay() + .getSize(szWindow) + } + + /* return status bar height on basis of device display metrics */ + private fun getStatusBarHeight(): Int { + return ceil( + (25 * requireActivity().applicationContext.resources.displayMetrics.density).toDouble() + ).toInt() + } + + private class MyGestureListener(val onTabCall: () -> Unit, val miniCircleDoubleTap: () -> Unit) : GestureDetector.SimpleOnGestureListener() { + + override fun onSingleTapConfirmed(event: MotionEvent): Boolean { + onTabCall() + return true + } + + override fun onDoubleTap(e: MotionEvent?): Boolean { + miniCircleDoubleTap() + return super.onDoubleTap(e) + } + + } + + companion object { + @JvmStatic + fun newInstance(args: Bundle) = + VideoCallFragment().apply { + arguments = args + } + + private val TAG = VideoCallFragment::class.java.simpleName + + private const val RC_SETTINGS_SCREEN_PERM = 123 + private const val RC_VIDEO_APP_PERM = 124 + + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt new file mode 100644 index 00000000..1a307eb5 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/DynamicVideoRenderer.kt @@ -0,0 +1,379 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + +/* +* https://nhancv.medium.com/android-how-to-make-a-circular-view-as-a-thumbnail-of-opentok-27992aee15c9 +* to solve make circle video stream +* */ + +class DynamicVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface DynamicVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setDynamicVideoRendererMetadataListener(metadataListener: DynamicVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + fun enableThumbnailCircle(enable: Boolean) { + mRenderer.requestEnableThumbnailCircle = enable + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var requestEnableThumbnailCircle = false + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform int enableCircle; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + if (enableCircle > 0) { + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); + } + else { + gl_FragColor = vec4(r, g, b, 1.0); + } +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun enableThumbnailCircle(enable: Boolean) { + GLES20.glUseProgram(mProgram) + val enableCircleLocation = GLES20.glGetUniformLocation(mProgram, "enableCircle") + GLES20.glUniform1i(enableCircleLocation, if (enable) 1 else 0) + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: DynamicVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + enableThumbnailCircle(requestEnableThumbnailCircle) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt new file mode 100644 index 00000000..b9b5a245 --- /dev/null +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/util/ThumbnailCircleVideoRenderer.kt @@ -0,0 +1,357 @@ +package com.hmg.hmgDr.util + +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.opengl.GLES20 +import android.opengl.GLSurfaceView +import android.opengl.Matrix +import android.view.View +import com.opentok.android.BaseVideoRenderer +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import java.nio.ShortBuffer +import java.util.concurrent.locks.ReentrantLock +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 + + +class ThumbnailCircleVideoRenderer(private val mContext: Context) : BaseVideoRenderer() { + private val mView: GLSurfaceView = GLSurfaceView(mContext) + private val mRenderer: MyRenderer + + interface ThumbnailCircleVideoRendererMetadataListener { + fun onMetadataReady(metadata: ByteArray?) + } + + fun setThumbnailCircleVideoRendererMetadataListener(metadataListener: ThumbnailCircleVideoRendererMetadataListener?) { + mRenderer.metadataListener = metadataListener + } + + internal class MyRenderer : GLSurfaceView.Renderer { + var mTextureIds = IntArray(3) + var mScaleMatrix = FloatArray(16) + private val mVertexBuffer: FloatBuffer + private val mTextureBuffer: FloatBuffer + private val mDrawListBuffer: ShortBuffer + var mVideoFitEnabled = true + var mVideoDisabled = false + private val mVertexIndex = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw + + // vertices + private val vertexShaderCode = """uniform mat4 uMVPMatrix;attribute vec4 aPosition; +attribute vec2 aTextureCoord; +varying vec2 vTextureCoord; +void main() { + gl_Position = uMVPMatrix * aPosition; + vTextureCoord = aTextureCoord; +} +""" + private val fragmentShaderCode = """precision mediump float; +uniform sampler2D Ytex; +uniform sampler2D Utex,Vtex; +uniform vec2 radiusDp; +varying vec2 vTextureCoord; +void main(void) { + float nx,ny,r,g,b,y,u,v; + mediump vec4 txl,ux,vx; nx=vTextureCoord[0]; + ny=vTextureCoord[1]; + y=texture2D(Ytex,vec2(nx,ny)).r; + u=texture2D(Utex,vec2(nx,ny)).r; + v=texture2D(Vtex,vec2(nx,ny)).r; + y=1.1643*(y-0.0625); + u=u-0.5; + v=v-0.5; + r=y+1.5958*v; + g=y-0.39173*u-0.81290*v; + b=y+2.017*u; + float radius = 0.5; + vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0); + vec4 color1 = vec4(r, g, b, 1.0); + vec2 st = (gl_FragCoord.xy/radiusDp.xy); float dist = radius - distance(st,vec2(0.5)); + float t = 1.0; + if (dist < 0.0) t = 0.0; + gl_FragColor = mix(color0, color1, t); +} +""" + var mFrameLock = ReentrantLock() + var mCurrentFrame: Frame? = null + private var mProgram = 0 + private var mTextureWidth = 0 + private var mTextureHeight = 0 + private var mViewportWidth = 0 + private var mViewportHeight = 0 + override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, + vertexShaderCode) + val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, + fragmentShaderCode) + mProgram = GLES20.glCreateProgram() // create empty OpenGL ES + // Program + GLES20.glAttachShader(mProgram, vertexShader) // add the vertex + // shader to program + GLES20.glAttachShader(mProgram, fragmentShader) // add the fragment + // shader to + // program + GLES20.glLinkProgram(mProgram) + val positionHandle = GLES20.glGetAttribLocation(mProgram, + "aPosition") + val textureHandle = GLES20.glGetAttribLocation(mProgram, + "aTextureCoord") + GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, + GLES20.GL_FLOAT, false, COORDS_PER_VERTEX * 4, + mVertexBuffer) + GLES20.glEnableVertexAttribArray(positionHandle) + GLES20.glVertexAttribPointer(textureHandle, + TEXTURECOORDS_PER_VERTEX, GLES20.GL_FLOAT, false, + TEXTURECOORDS_PER_VERTEX * 4, mTextureBuffer) + GLES20.glEnableVertexAttribArray(textureHandle) + GLES20.glUseProgram(mProgram) + var i = GLES20.glGetUniformLocation(mProgram, "Ytex") + GLES20.glUniform1i(i, 0) /* Bind Ytex to texture unit 0 */ + i = GLES20.glGetUniformLocation(mProgram, "Utex") + GLES20.glUniform1i(i, 1) /* Bind Utex to texture unit 1 */ + i = GLES20.glGetUniformLocation(mProgram, "Vtex") + GLES20.glUniform1i(i, 2) /* Bind Vtex to texture unit 2 */ + val radiusDpLocation = GLES20.glGetUniformLocation(mProgram, "radiusDp") + val radiusDp = (Resources.getSystem().displayMetrics.density * THUMBNAIL_SIZE).toInt() + GLES20.glUniform2f(radiusDpLocation, radiusDp.toFloat(), radiusDp.toFloat()) + mTextureWidth = 0 + mTextureHeight = 0 + } + + fun setupTextures(frame: Frame) { + if (mTextureIds[0] != 0) { + GLES20.glDeleteTextures(3, mTextureIds, 0) + } + GLES20.glGenTextures(3, mTextureIds, 0) + val w = frame.width + val h = frame.height + val hw = w + 1 shr 1 + val hh = h + 1 shr 1 + initializeTexture(GLES20.GL_TEXTURE0, mTextureIds[0], w, h) + initializeTexture(GLES20.GL_TEXTURE1, mTextureIds[1], hw, hh) + initializeTexture(GLES20.GL_TEXTURE2, mTextureIds[2], hw, hh) + mTextureWidth = frame.width + mTextureHeight = frame.height + } + + fun updateTextures(frame: Frame) { + val width = frame.width + val height = frame.height + val half_width = width + 1 shr 1 + val half_height = height + 1 shr 1 + val y_size = width * height + val uv_size = half_width * half_height + val bb = frame.buffer + // If we are reusing this frame, make sure we reset position and + // limit + bb.clear() + if (bb.remaining() == y_size + uv_size * 2) { + bb.position(0) + GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1) + GLES20.glPixelStorei(GLES20.GL_PACK_ALIGNMENT, 1) + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[0]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, + height, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, + bb) + bb.position(y_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE1) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[1]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + bb.position(y_size + uv_size) + GLES20.glActiveTexture(GLES20.GL_TEXTURE2) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIds[2]) + GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, + half_width, half_height, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, bb) + } else { + mTextureWidth = 0 + mTextureHeight = 0 + } + } + + override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { + GLES20.glViewport(0, 0, width, height) + mViewportWidth = width + mViewportHeight = height + } + + var metadataListener: ThumbnailCircleVideoRendererMetadataListener? = null + override fun onDrawFrame(gl: GL10) { + gl.glClearColor(0f, 0f, 0f, 0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + mFrameLock.lock() + if (mCurrentFrame != null && !mVideoDisabled) { + GLES20.glUseProgram(mProgram) + if (mTextureWidth != mCurrentFrame!!.width + || mTextureHeight != mCurrentFrame!!.height) { + setupTextures(mCurrentFrame!!) + } + updateTextures(mCurrentFrame!!) + Matrix.setIdentityM(mScaleMatrix, 0) + var scaleX = 1.0f + var scaleY = 1.0f + val ratio = (mCurrentFrame!!.width.toFloat() + / mCurrentFrame!!.height) + val vratio = mViewportWidth.toFloat() / mViewportHeight + if (mVideoFitEnabled) { + if (ratio > vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } else { + if (ratio < vratio) { + scaleY = vratio / ratio + } else { + scaleX = ratio / vratio + } + } + Matrix.scaleM(mScaleMatrix, 0, + scaleX * if (mCurrentFrame!!.isMirroredX) -1.0f else 1.0f, + scaleY, 1f) + metadataListener?.onMetadataReady(mCurrentFrame!!.metadata) + val mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, + "uMVPMatrix") + GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, + mScaleMatrix, 0) + GLES20.glDrawElements(GLES20.GL_TRIANGLES, mVertexIndex.size, + GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer) + } else { + //black frame when video is disabled + gl.glClearColor(0f, 0f, 0f, 1f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) + } + mFrameLock.unlock() + } + + fun displayFrame(frame: Frame?) { + mFrameLock.lock() + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = frame + mFrameLock.unlock() + } + + fun disableVideo(b: Boolean) { + mFrameLock.lock() + mVideoDisabled = b + if (mVideoDisabled) { + if (mCurrentFrame != null) { + mCurrentFrame!!.recycle() + } + mCurrentFrame = null + } + mFrameLock.unlock() + } + + fun enableVideoFit(enableVideoFit: Boolean) { + mVideoFitEnabled = enableVideoFit + } + + companion object { + // number of coordinates per vertex in this array + const val COORDS_PER_VERTEX = 3 + const val TEXTURECOORDS_PER_VERTEX = 2 + var mXYZCoords = floatArrayOf( + -1.0f, 1.0f, 0.0f, // top left + -1.0f, -1.0f, 0.0f, // bottom left + 1.0f, -1.0f, 0.0f, // bottom right + 1.0f, 1.0f, 0.0f // top right + ) + var mUVCoords = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + fun initializeTexture(name: Int, id: Int, width: Int, height: Int) { + GLES20.glActiveTexture(name) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()) + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, + width, height, 0, GLES20.GL_LUMINANCE, + GLES20.GL_UNSIGNED_BYTE, null) + } + + fun loadShader(type: Int, shaderCode: String?): Int { + val shader = GLES20.glCreateShader(type) + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) + return shader + } + } + + init { + val bb = ByteBuffer.allocateDirect(mXYZCoords.size * 4) + bb.order(ByteOrder.nativeOrder()) + mVertexBuffer = bb.asFloatBuffer() + mVertexBuffer.put(mXYZCoords) + mVertexBuffer.position(0) + val tb = ByteBuffer.allocateDirect(mUVCoords.size * 4) + tb.order(ByteOrder.nativeOrder()) + mTextureBuffer = tb.asFloatBuffer() + mTextureBuffer.put(mUVCoords) + mTextureBuffer.position(0) + val dlb = ByteBuffer.allocateDirect(mVertexIndex.size * 2) + dlb.order(ByteOrder.nativeOrder()) + mDrawListBuffer = dlb.asShortBuffer() + mDrawListBuffer.put(mVertexIndex) + mDrawListBuffer.position(0) + } + } + + override fun onFrame(frame: Frame) { + mRenderer.displayFrame(frame) + mView.requestRender() + } + + override fun setStyle(key: String, value: String) { + if (STYLE_VIDEO_SCALE == key) { + if (STYLE_VIDEO_FIT == value) { + mRenderer.enableVideoFit(true) + } else if (STYLE_VIDEO_FILL == value) { + mRenderer.enableVideoFit(false) + } + } + } + + override fun onVideoPropertiesChanged(videoEnabled: Boolean) { + mRenderer.disableVideo(!videoEnabled) + } + + override fun getView(): View { + return mView + } + + override fun onPause() { + mView.onPause() + } + + override fun onResume() { + mView.onResume() + } + + companion object { + private const val THUMBNAIL_SIZE = 90 //in dp + } + + init { + mView.setEGLContextClientVersion(2) + mView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) + mView.holder.setFormat(PixelFormat.TRANSLUCENT) + mRenderer = MyRenderer() + mView.setRenderer(mRenderer) + mView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + } +} diff --git a/android/app/src/main/res/drawable/call.png b/android/app/src/main/res/drawable/call.png index fc00f4f9..52f8e267 100644 Binary files a/android/app/src/main/res/drawable/call.png and b/android/app/src/main/res/drawable/call.png differ diff --git a/android/app/src/main/res/drawable/camera_back.png b/android/app/src/main/res/drawable/camera_back.png new file mode 100644 index 00000000..c3d63ac3 Binary files /dev/null and b/android/app/src/main/res/drawable/camera_back.png differ diff --git a/android/app/src/main/res/drawable/camera_front.png b/android/app/src/main/res/drawable/camera_front.png new file mode 100644 index 00000000..332ab0f5 Binary files /dev/null and b/android/app/src/main/res/drawable/camera_front.png differ diff --git a/android/app/src/main/res/drawable/circle_shape.xml b/android/app/src/main/res/drawable/circle_shape.xml new file mode 100644 index 00000000..27b49f9b --- /dev/null +++ b/android/app/src/main/res/drawable/circle_shape.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/expand.png b/android/app/src/main/res/drawable/expand.png new file mode 100644 index 00000000..7020dc2e Binary files /dev/null and b/android/app/src/main/res/drawable/expand.png differ diff --git a/android/app/src/main/res/drawable/flip_disapled.png b/android/app/src/main/res/drawable/flip_disapled.png deleted file mode 100644 index 5226029e..00000000 Binary files a/android/app/src/main/res/drawable/flip_disapled.png and /dev/null differ diff --git a/android/app/src/main/res/drawable/flip_enabled.png b/android/app/src/main/res/drawable/flip_enabled.png deleted file mode 100644 index 152dc10e..00000000 Binary files a/android/app/src/main/res/drawable/flip_enabled.png and /dev/null differ diff --git a/android/app/src/main/res/drawable/ic_mini.xml b/android/app/src/main/res/drawable/ic_mini.xml new file mode 100644 index 00000000..128a7430 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_mini.xml @@ -0,0 +1,5 @@ + + + diff --git a/android/app/src/main/res/drawable/layout_rounded_bg.xml b/android/app/src/main/res/drawable/layout_rounded_bg.xml new file mode 100644 index 00000000..ce73e763 --- /dev/null +++ b/android/app/src/main/res/drawable/layout_rounded_bg.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/android/app/src/main/res/drawable/mic_disabled.png b/android/app/src/main/res/drawable/mic_disabled.png index 3603df75..266cb6c7 100644 Binary files a/android/app/src/main/res/drawable/mic_disabled.png and b/android/app/src/main/res/drawable/mic_disabled.png differ diff --git a/android/app/src/main/res/drawable/mic_enabled.png b/android/app/src/main/res/drawable/mic_enabled.png index 5d9aa677..ef7617f7 100644 Binary files a/android/app/src/main/res/drawable/mic_enabled.png and b/android/app/src/main/res/drawable/mic_enabled.png differ diff --git a/android/app/src/main/res/drawable/reducing.png b/android/app/src/main/res/drawable/reducing.png new file mode 100644 index 00000000..59f2c9e6 Binary files /dev/null and b/android/app/src/main/res/drawable/reducing.png differ diff --git a/android/app/src/main/res/drawable/shape_capsule.xml b/android/app/src/main/res/drawable/shape_capsule.xml new file mode 100644 index 00000000..a5dcdd09 --- /dev/null +++ b/android/app/src/main/res/drawable/shape_capsule.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/video_disabled.png b/android/app/src/main/res/drawable/video_disabled.png new file mode 100644 index 00000000..d6ccbe7a Binary files /dev/null and b/android/app/src/main/res/drawable/video_disabled.png differ diff --git a/android/app/src/main/res/drawable/video_disanabled.png b/android/app/src/main/res/drawable/video_disanabled.png deleted file mode 100644 index 5c20c7bd..00000000 Binary files a/android/app/src/main/res/drawable/video_disanabled.png and /dev/null differ diff --git a/android/app/src/main/res/drawable/video_enabled.png b/android/app/src/main/res/drawable/video_enabled.png index 23331e30..6fcbe750 100644 Binary files a/android/app/src/main/res/drawable/video_enabled.png and b/android/app/src/main/res/drawable/video_enabled.png differ diff --git a/android/app/src/main/res/layout/activity_video_call.xml b/android/app/src/main/res/layout/activity_video_call.xml index 2dcf2ba4..a54e57b3 100644 --- a/android/app/src/main/res/layout/activity_video_call.xml +++ b/android/app/src/main/res/layout/activity_video_call.xml @@ -1,169 +1,197 @@ - + android:background="@color/text_color" + android:orientation="vertical"> + - - + + + + + android:layout_alignParentEnd="true" + android:background="@drawable/shape_capsule" + android:padding="@dimen/padding_space_small"> + + + + - + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/control_panel" + app:layout_constraintTop_toBottomOf="@+id/layout_name"> + + + + + + + android:layout_below="@+id/layout_mini" + android:background="@color/remoteBackground"> - - - - + - - + - + + + + + + + + android:padding="@dimen/padding_space_big" + app:layout_constraintBottom_toBottomOf="parent"> + android:src="@drawable/call" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/reducing" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/video_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_minimize" + app:layout_constraintTop_toTopOf="parent" /> + android:src="@drawable/mic_enabled" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_camera" + app:layout_constraintTop_toTopOf="parent" /> + + - + android:src="@drawable/audio_enabled" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/btn_mic" + app:layout_constraintTop_toTopOf="parent" /> + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index d1d2a305..f52c2cf2 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -5,7 +5,17 @@ #fc3850 #e4e9f2 + #80757575 + #00ffffff + + #827b92 #484258 + #FF2E303A + + #fff + #000 + #389842 + #d51e26 diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml index 79f3d269..0694f5f4 100644 --- a/android/app/src/main/res/values/dimens.xml +++ b/android/app/src/main/res/values/dimens.xml @@ -3,20 +3,39 @@ 16dp 16dp 28dp + 12dp 24dp 60dp 54dp + 52dp + 24dp + + 24dp + 25dp 88dp + 40dp 117dp + 50dp 50dp + 25dp 100dp + 40dp 90dp - - 24dp - 25dp + + 14sp + 16sp + 22sp + + + 4dp + 8sp + 16dp + 24dp + + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 74349756..bc694f7c 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -4,5 +4,7 @@ الوقت المتبقي بالثانيه: Settings Cancel + + Hello blank fragment \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 24355fae..e13b5b14 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -16,4 +16,21 @@ true @null + + + diff --git a/android/build.gradle b/android/build.gradle index 49bd99ef..4cb72d20 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -16,10 +16,12 @@ allprojects { repositories { google() jcenter() + mavenCentral() maven { url 'https://tokbox.bintray.com/maven' } } } + rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" diff --git a/dart b/dart new file mode 100644 index 00000000..e69de29b diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 00000000..c2335042 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,92 @@ +# Uncomment this line to define a global platform for your project + platform :ios, '11.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 parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + 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 + end + generated_key_values +end + +target 'Runner' do + use_frameworks! + use_modular_headers! + + # 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. + + 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']; + + 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 + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + pod 'OpenTok' + pod 'Alamofire', '~> 5.2' + pod 'AADraggableView' + # Plugin Pods + + # 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') + 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 + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9efb7e0d..c31cbe8e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,12 +9,16 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 29211E4225C172B700DD740D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 29211E4125C172B700DD740D /* GoogleService-Info.plist */; }; + 300790FA266FB14B0052174C /* VCEmbeder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300790F9266FB14B0052174C /* VCEmbeder.swift */; }; + 300790FC26710CAB0052174C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300790FB26710CAB0052174C /* Extensions.swift */; }; + 30F70E6C266F56FD005D8F8E /* MainAppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */; }; + 30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */; }; 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 */; }; - 9CE61EBD24AB366E008D68DD /* VideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */; }; + 9CE61EBD24AB366E008D68DD /* VideoCallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61EBC24AB366E008D68DD /* VideoCallViewController.swift */; }; 9CE61ECD24ADBB4C008D68DD /* ICallProtocoll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */; }; B650DC3076E9D70CB188286A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A5F83B23AB032D1E096663 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -37,6 +41,10 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 29211CD725C165D600DD740D /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = ""; }; 29211E4125C172B700DD740D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 300790F9266FB14B0052174C /* VCEmbeder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VCEmbeder.swift; sourceTree = ""; }; + 300790FB26710CAB0052174C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainAppViewController.swift; sourceTree = ""; }; + 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallRequestParameters.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 = ""; }; @@ -50,7 +58,7 @@ 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 = ""; }; - 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoViewController.swift; sourceTree = ""; }; + 9CE61EBC24AB366E008D68DD /* VideoCallViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallViewController.swift; sourceTree = ""; }; 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICallProtocoll.swift; sourceTree = ""; }; 9D4B7DB43C6A6C849D2387CE /* 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 = ""; }; E698D7B14B12DF768FE47A1A /* 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 = ""; }; @@ -68,6 +76,31 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 300790F8266FB0F10052174C /* helpers */ = { + isa = PBXGroup; + children = ( + 300790F9266FB14B0052174C /* VCEmbeder.swift */, + 300790FB26710CAB0052174C /* Extensions.swift */, + ); + name = helpers; + sourceTree = ""; + }; + 30F70E6A266F56C9005D8F8E /* controllers */ = { + isa = PBXGroup; + children = ( + 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */, + ); + name = controllers; + sourceTree = ""; + }; + 30F70E6D266F64F8005D8F8E /* Models */ = { + isa = PBXGroup; + children = ( + 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */, + ); + name = Models; + sourceTree = ""; + }; 7D66D387293CE5376A07EC5F /* Pods */ = { isa = PBXGroup; children = ( @@ -111,6 +144,9 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 300790F8266FB0F10052174C /* helpers */, + 30F70E6D266F64F8005D8F8E /* Models */, + 30F70E6A266F56C9005D8F8E /* controllers */, 29211E4125C172B700DD740D /* GoogleService-Info.plist */, 29211CD725C165D600DD740D /* RunnerRelease.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, @@ -122,7 +158,7 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - 9CE61EBC24AB366E008D68DD /* VideoViewController.swift */, + 9CE61EBC24AB366E008D68DD /* VideoCallViewController.swift */, 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */, ); path = Runner; @@ -359,10 +395,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 300790FA266FB14B0052174C /* VCEmbeder.swift in Sources */, + 30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 9CE61EBD24AB366E008D68DD /* VideoViewController.swift in Sources */, + 300790FC26710CAB0052174C /* Extensions.swift in Sources */, + 9CE61EBD24AB366E008D68DD /* VideoCallViewController.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 9CE61ECD24ADBB4C008D68DD /* ICallProtocoll.swift in Sources */, + 30F70E6C266F56FD005D8F8E /* MainAppViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb2dffc4..a28140cf 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -27,6 +27,8 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + - - + + + + Bool { - let controller : FlutterViewController = window?.rootViewController as! FlutterViewController - let videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", - binaryMessenger: controller.binaryMessenger) - videoCallChannel.setMethodCallHandler({ - (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in - self.result = result - switch call.method { - case "openVideoCall": - do { - let arguments = call.arguments as? NSDictionary - let kApiKey = arguments!["kApiKey"] as? String - let kSessionId = arguments!["kSessionId"] as? String - let kToken = arguments!["kToken"] as? String - let appLang = arguments!["appLang"] as? String - let vC_ID = arguments!["VC_ID"] as? Int - let tokenID = arguments!["TokenID"] as? String - let generalId = arguments!["generalId"] as? String - let doctorId = arguments!["DoctorId"] as? Int - let baseUrl = arguments!["baseUrl"] as? String - - self.openVideoChat(result: result,kApiKey: kApiKey!,kSessionId:kSessionId!,kToken: kToken!, appLang: appLang!, vC_ID: vC_ID!,tokenID: tokenID!,generalId: generalId!,doctorId: doctorId!, baseUrl: baseUrl!) - } - default: - result(FlutterMethodNotImplemented) - } - }) - GeneratedPluginRegistrant.register(with: self) + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } @@ -61,7 +35,7 @@ import OpenTok let storyboard = UIStoryboard(name: "Main", bundle: nil) let identifier = "ViewControllerNav" let navVC = storyboard.instantiateViewController(withIdentifier: identifier) as! UINavigationController - let videoVC = navVC.viewControllers.first as! ViewController + let videoVC = navVC.viewControllers.first as! VideoCallViewController videoVC.kApiKey=kApiKey videoVC.kSessionId=kSessionId videoVC.kToken=kToken @@ -75,6 +49,6 @@ import OpenTok navVC.modalPresentationStyle = .fullScreen window.rootViewController?.present(navVC, animated: true, completion: nil) - } } + diff --git a/ios/Runner/Assets.xcassets/Contents.json b/ios/Runner/Assets.xcassets/Contents.json index da4a164c..73c00596 100755 --- a/ios/Runner/Assets.xcassets/Contents.json +++ b/ios/Runner/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/ios/Runner/Assets.xcassets/camera_back.imageset/Contents.json b/ios/Runner/Assets.xcassets/camera_back.imageset/Contents.json new file mode 100644 index 00000000..ab08ef1a --- /dev/null +++ b/ios/Runner/Assets.xcassets/camera_back.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "camera_back.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/camera_back.imageset/camera_back.png b/ios/Runner/Assets.xcassets/camera_back.imageset/camera_back.png new file mode 100644 index 00000000..c3d63ac3 Binary files /dev/null and b/ios/Runner/Assets.xcassets/camera_back.imageset/camera_back.png differ diff --git a/ios/Runner/Assets.xcassets/camera_front.imageset/Contents.json b/ios/Runner/Assets.xcassets/camera_front.imageset/Contents.json new file mode 100644 index 00000000..a0e93123 --- /dev/null +++ b/ios/Runner/Assets.xcassets/camera_front.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "camera_front.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/camera_front.imageset/camera_front.png b/ios/Runner/Assets.xcassets/camera_front.imageset/camera_front.png new file mode 100644 index 00000000..332ab0f5 Binary files /dev/null and b/ios/Runner/Assets.xcassets/camera_front.imageset/camera_front.png differ diff --git a/ios/Runner/Assets.xcassets/end_call.imageset/Contents.json b/ios/Runner/Assets.xcassets/end_call.imageset/Contents.json new file mode 100644 index 00000000..3762a5af --- /dev/null +++ b/ios/Runner/Assets.xcassets/end_call.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "end_call.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/end_call.imageset/end_call.png b/ios/Runner/Assets.xcassets/end_call.imageset/end_call.png new file mode 100644 index 00000000..52f8e267 Binary files /dev/null and b/ios/Runner/Assets.xcassets/end_call.imageset/end_call.png differ diff --git a/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json b/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json new file mode 100644 index 00000000..1ecfeae9 --- /dev/null +++ b/ios/Runner/Assets.xcassets/expand_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "expand.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/expand_video.imageset/expand.png b/ios/Runner/Assets.xcassets/expand_video.imageset/expand.png new file mode 100644 index 00000000..7020dc2e Binary files /dev/null and b/ios/Runner/Assets.xcassets/expand_video.imageset/expand.png differ diff --git a/ios/Runner/Assets.xcassets/float_video.imageset/Contents.json b/ios/Runner/Assets.xcassets/float_video.imageset/Contents.json new file mode 100644 index 00000000..e3a2ec5a --- /dev/null +++ b/ios/Runner/Assets.xcassets/float_video.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 8024.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/float_video.imageset/Group 8024.png b/ios/Runner/Assets.xcassets/float_video.imageset/Group 8024.png new file mode 100644 index 00000000..59f2c9e6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/float_video.imageset/Group 8024.png differ diff --git a/ios/Runner/Assets.xcassets/hide_video_icon.imageset/Contents.json b/ios/Runner/Assets.xcassets/hide_video_icon.imageset/Contents.json new file mode 100644 index 00000000..91a3b7b1 --- /dev/null +++ b/ios/Runner/Assets.xcassets/hide_video_icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "hide_video_icon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/hide_video_icon.imageset/hide_video_icon.png b/ios/Runner/Assets.xcassets/hide_video_icon.imageset/hide_video_icon.png new file mode 100644 index 00000000..40889f77 Binary files /dev/null and b/ios/Runner/Assets.xcassets/hide_video_icon.imageset/hide_video_icon.png differ diff --git a/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json b/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json new file mode 100644 index 00000000..2a0f4d2e --- /dev/null +++ b/ios/Runner/Assets.xcassets/mic_mute.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "mic_mute.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/mic_mute.imageset/mic_mute.png b/ios/Runner/Assets.xcassets/mic_mute.imageset/mic_mute.png new file mode 100644 index 00000000..266cb6c7 Binary files /dev/null and b/ios/Runner/Assets.xcassets/mic_mute.imageset/mic_mute.png differ diff --git a/ios/Runner/Assets.xcassets/mic_unmute.imageset/Contents.json b/ios/Runner/Assets.xcassets/mic_unmute.imageset/Contents.json new file mode 100644 index 00000000..8e85d01a --- /dev/null +++ b/ios/Runner/Assets.xcassets/mic_unmute.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 8020.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/mic_unmute.imageset/Group 8020.png b/ios/Runner/Assets.xcassets/mic_unmute.imageset/Group 8020.png new file mode 100644 index 00000000..ef7617f7 Binary files /dev/null and b/ios/Runner/Assets.xcassets/mic_unmute.imageset/Group 8020.png differ diff --git a/ios/Runner/Assets.xcassets/video_mute.imageset/Contents.json b/ios/Runner/Assets.xcassets/video_mute.imageset/Contents.json new file mode 100644 index 00000000..4403d6ee --- /dev/null +++ b/ios/Runner/Assets.xcassets/video_mute.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "video_mute.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/video_mute.imageset/video_mute.png b/ios/Runner/Assets.xcassets/video_mute.imageset/video_mute.png new file mode 100644 index 00000000..d6ccbe7a Binary files /dev/null and b/ios/Runner/Assets.xcassets/video_mute.imageset/video_mute.png differ diff --git a/ios/Runner/Assets.xcassets/video_unmute.imageset/Contents.json b/ios/Runner/Assets.xcassets/video_unmute.imageset/Contents.json new file mode 100644 index 00000000..51724501 --- /dev/null +++ b/ios/Runner/Assets.xcassets/video_unmute.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Group 8022.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/video_unmute.imageset/Group 8022.png b/ios/Runner/Assets.xcassets/video_unmute.imageset/Group 8022.png new file mode 100644 index 00000000..6fcbe750 Binary files /dev/null and b/ios/Runner/Assets.xcassets/video_unmute.imageset/Group 8022.png differ diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index 73e18f76..2bdee5a2 100755 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,296 +1,366 @@ - - + + - + - + - + - + - + - + - + - + - - - + + - + - - + - - - - - - - - + + - - - + + + + + + + + + + + + - - + + + + + - - - - - - + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - + - - - - - - - - - - + + + + + + + + + + - - + - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + - - - - - - - - - - + + + + + + + + + diff --git a/ios/Runner/Extensions.swift b/ios/Runner/Extensions.swift new file mode 100644 index 00000000..b79c8deb --- /dev/null +++ b/ios/Runner/Extensions.swift @@ -0,0 +1,27 @@ +// +// Extensions.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 09/06/2021. +// Copyright © 2021 The Chromium Authors. All rights reserved. +// +import AADraggableView + +extension AADraggableView{ + func enable(_ enable:Bool){ + isEnabled = enable + if enable == false{ + gestureRecognizers?.forEach({ gest in + removeGestureRecognizer(gest) + }) + } + } +} + +extension UIView{ + func hidden(_ hidden:Bool, rootView:UIView){ + UIView.transition(with: rootView, duration: 0.5, options: .transitionCrossDissolve, animations: { + self.isHidden = hidden + }) + } +} diff --git a/ios/Runner/MainAppViewController.swift b/ios/Runner/MainAppViewController.swift new file mode 100644 index 00000000..c7b7a18d --- /dev/null +++ b/ios/Runner/MainAppViewController.swift @@ -0,0 +1,190 @@ +// +// MainAppViewController.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 08/06/2021. +// Copyright © 2021 The Chromium Authors. All rights reserved. +// + +import Foundation +import AADraggableView + +class MainAppViewController: FlutterViewController{ + var videoCallContainer:AADraggableView! + var videoCallViewController:VideoCallViewController! + var videoCallFlutterResult:FlutterResult? + var vdoCallViewFloatRectConstraint:[NSLayoutConstraint]! + var vdoCallViewFullConstraint:[NSLayoutConstraint]! + var vdoCallViewFloatCircleConstraint:[NSLayoutConstraint]! + + + override func viewDidLoad() { + super.viewDidLoad() + initFlutterBridge() + prepareVideoCallView() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + var videoCallChannel:FlutterMethodChannel? + private func initFlutterBridge(){ + videoCallChannel = FlutterMethodChannel(name: "Dr.cloudSolution/videoCall", binaryMessenger: binaryMessenger) + videoCallChannel?.setMethodCallHandler({ + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + switch call.method { + case "openVideoCall": + self.startVideoCall(result: result, call: call) + default: + result(FlutterMethodNotImplemented) + } + }) + } + +} + + +// Video Call Functions +extension MainAppViewController : ICallProtocol{ + + func prepareVideoCallView(){ + videoCallContainer = AADraggableView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)) + videoCallContainer.backgroundColor = UIColor.black + videoCallContainer.isHidden = true + videoCallContainer.clipsToBounds = true + videoCallContainer.padding = 20 + videoCallContainer.reposition = .edgesOnly + videoCallContainer.isEnabled = false + + view.addSubview(videoCallContainer) + setVideoViewConstrints() + NSLayoutConstraint.activate(vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(vdoCallViewFloatRectConstraint) + + ViewEmbedder.embed( + withIdentifier: "videoCall", // Storyboard ID + parent: self, + container: self.videoCallContainer){ vc in + self.videoCallViewController = vc as? VideoCallViewController + + } + } + + private func showVideo(show:Bool){ + self.videoCallContainer.hidden(!show, rootView: view) + } + + private func startVideoCall(result: @escaping FlutterResult, call:FlutterMethodCall) { + videoCallFlutterResult = result + + if let arguments = call.arguments as? NSDictionary{ + showVideoCallView(true) + + videoCallViewController.onRectFloat = { isRectFloat in + self.rectFloatVideoCallView(isRectFloat) + } + + videoCallViewController.onCircleFloat = { isCircleFloat in + self.circleFloatVideoCallView(isCircleFloat) + } + videoCallViewController.onCallConnect = { + self.videoCallChannel?.invokeMethod("onCallConnected",arguments: nil) + } + videoCallViewController.onCallDisconnect = { + self.showVideoCallView(false) + self.videoCallViewController.minimizeVideoState(state: false) + self.videoCallChannel?.invokeMethod("onCallDisconnected",arguments: nil) + } + videoCallViewController.callBack = self + videoCallViewController.start(params: VideoCallRequestParameters(dictionary: arguments)) + } + + + } + + private func rectFloatVideoCallView(_ value:Bool){ + videoCallContainer.enable(value) + + UIView.animate(withDuration: 0.5) { + if(value){ + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFloatRectConstraint) + }else{ + NSLayoutConstraint.deactivate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFullConstraint) + } + self.videoCallContainer.layer.cornerRadius = value ? 10 : 0 + self.videoCallContainer.layer.borderColor = value ? UIColor.white.cgColor : nil + self.videoCallContainer.layer.borderWidth = value ? 2 : 0 + self.view.layoutIfNeeded() + } + } + + private func circleFloatVideoCallView(_ value:Bool){ + videoCallContainer.reposition = value ? .sticky : .edgesOnly + + UIView.animate(withDuration: 0.5) { + if(value){ + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.activate(self.vdoCallViewFloatCircleConstraint) + self.videoCallContainer.layer.cornerRadius = 35 + }else{ + NSLayoutConstraint.activate(self.vdoCallViewFloatRectConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFullConstraint) + NSLayoutConstraint.deactivate(self.vdoCallViewFloatCircleConstraint) + self.videoCallContainer.layer.cornerRadius = 10 + + } + self.videoCallContainer.layer.borderColor = value ? UIColor.white.cgColor : nil + self.videoCallContainer.layer.borderWidth = value ? 2 : 0 + self.view.layoutIfNeeded() + } + } + + private func showVideoCallView(_ value:Bool){ + self.videoCallContainer.hidden(!value, rootView: view) + } + + func sessionDone(res: Any) { + videoCallFlutterResult?(res) + } + + func sessionNotResponded(res: Any) { + videoCallFlutterResult?(res) + } + + + func setVideoViewConstrints(){ + videoCallContainer.layer.shadowColor = UIColor.black.cgColor + videoCallContainer.layer.shadowOffset = CGSize(width: 1, height: 1) + videoCallContainer.layer.shadowRadius = 5 + + let screen = UIScreen.main.bounds + + videoCallContainer.translatesAutoresizingMaskIntoConstraints = false + + vdoCallViewFullConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor), + videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width), + videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height) + ] + vdoCallViewFloatRectConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 40), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), + videoCallContainer.widthAnchor.constraint(equalToConstant: screen.width/3), + videoCallContainer.heightAnchor.constraint(equalToConstant: screen.height/3.5) + ] + vdoCallViewFloatCircleConstraint = [ + videoCallContainer.topAnchor.constraint(equalTo: view.topAnchor, constant: 40), + videoCallContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), + videoCallContainer.widthAnchor.constraint(equalToConstant: 70), + videoCallContainer.heightAnchor.constraint(equalToConstant: 70) + ] + } + +} diff --git a/ios/Runner/VCEmbeder.swift b/ios/Runner/VCEmbeder.swift new file mode 100644 index 00000000..9617a247 --- /dev/null +++ b/ios/Runner/VCEmbeder.swift @@ -0,0 +1,78 @@ +// +// VCEmbeder.swift +// Runner +// +// Created by Zohaib Iqbal Kambrani on 08/06/2021. +// Copyright © 2021 The Chromium Authors. All rights reserved. +// + +import Foundation + +extension UIView { + func fill(to parent: UIView, animateDuration:Double = 0.5) { + self.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + self.leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + self.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + self.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + UIView.animate(withDuration: animateDuration) { + parent.layoutIfNeeded() + } + } + + func fillToParent(animateDuration:Double = 0.5) { + if let parent = self.superview{ + self.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true + self.leadingAnchor.constraint(equalTo: parent.leadingAnchor).isActive = true + self.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true + self.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true + UIView.animate(withDuration: animateDuration) { + parent.layoutIfNeeded() + } + } + } + + func fillInTo(view:UIView) { + view.addSubview(self) + fillToParent() + } +} + +class ViewEmbedder { + class func embed( + parent:UIViewController, + container:UIView, + child:UIViewController, + previous:UIViewController?){ + + if let previous = previous { + removeFromParent(vc: previous) + } + child.willMove(toParent: parent) + parent.addChild(child) + container.addSubview(child.view) + child.didMove(toParent: parent) + let w = container.frame.size.width; + let h = container.frame.size.height; + child.view.frame = CGRect(x: 0, y: 0, width: w, height: h) + child.view.backgroundColor = UIColor.black + + child.view.fill(to: container) + } + + class func removeFromParent(vc:UIViewController){ + vc.willMove(toParent: nil) + vc.view.removeFromSuperview() + vc.removeFromParent() + } + + class func embed(withIdentifier id:String, parent:UIViewController, container:UIView, completion:((UIViewController)->Void)? = nil){ + let vc = parent.storyboard!.instantiateViewController(withIdentifier: id) + embed( + parent: parent, + container: container, + child: vc, + previous: parent.children.first + ) + completion?(vc) + } +} diff --git a/ios/Runner/VideoCallRequestParameters.swift b/ios/Runner/VideoCallRequestParameters.swift new file mode 100644 index 00000000..543d7e8b --- /dev/null +++ b/ios/Runner/VideoCallRequestParameters.swift @@ -0,0 +1,29 @@ + + +import Foundation + +class VideoCallRequestParameters{ + var apiKey:String? + var sessionId:String? + var token:String? + var lang:String? + var vcId:Int? + var tokenId:String? + var generalId:String? + var doctorId:Int? + var baseUrl:String? + var patientName:String? + + init(dictionary:NSDictionary){ + self.apiKey = dictionary["kApiKey"] as? String + self.sessionId = dictionary["kSessionId"] as? String + self.token = dictionary["kToken"] as? String + self.lang = dictionary["appLang"] as? String + self.vcId = dictionary["VC_ID"] as? Int + self.tokenId = dictionary["TokenID"] as? String + self.generalId = dictionary["generalId"] as? String + self.doctorId = dictionary["DoctorId"] as? Int + self.baseUrl = dictionary["baseUrl"] as? String + self.patientName = dictionary["patientName"] as? String + } +} diff --git a/ios/Runner/VideoViewController.swift b/ios/Runner/VideoCallViewController.swift similarity index 62% rename from ios/Runner/VideoViewController.swift rename to ios/Runner/VideoCallViewController.swift index 44e45f3a..80a6fcb8 100644 --- a/ios/Runner/VideoViewController.swift +++ b/ios/Runner/VideoCallViewController.swift @@ -9,9 +9,9 @@ import UIKit import OpenTok import Alamofire +import AADraggableView - -class ViewController: UIViewController { +class VideoCallViewController: UIViewController { var session: OTSession? var publisher: OTPublisher? @@ -31,21 +31,191 @@ class ViewController: UIViewController { var callBack: ICallProtocol? var timer = Timer() - var seconds = 30 + var seconds = 55 var isUserConnect : Bool = false + var onRectFloat:((Bool)->Void)? = nil + var onCircleFloat:((Bool)->Void)? = nil + var onCallConnect:(()->Void)? = nil + var onCallDisconnect:(()->Void)? = nil + + + @IBOutlet weak var lblRemoteUsername: UILabel! + + // Bottom Actions + @IBOutlet weak var videoMuteBtn: UIButton! + @IBOutlet weak var micMuteBtn: UIButton! + @IBOutlet weak var camSwitchBtn: UIButton! + + @IBOutlet var minimizeConstraint: [NSLayoutConstraint]! + @IBOutlet var maximisedConstraint: [NSLayoutConstraint]! + + @IBOutlet weak var btnMinimize: UIButton! + @IBOutlet weak var hideVideoBtn: UIButton! + var localVideoDraggable:AADraggableView? + @IBOutlet weak var controlButtons: UIView! + @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! + @IBOutlet weak var localVideoMutedBg: UIView! + + @IBOutlet weak var btnScreenTap: UIButton! + @IBOutlet weak var localVideoContainer: UIView! + @IBOutlet weak var topBar: UIView! + @IBOutlet weak var lblCallDuration: UILabel! + @IBOutlet weak var fullVideoView: UIView! + @IBOutlet weak var smallVideoView: UIView!{ + didSet{ + smallVideoView.layer.borderColor = UIColor.white.cgColor + localVideoDraggable = smallVideoView?.superview as? AADraggableView + localVideoDraggable?.reposition = .edgesOnly + } + } override func viewDidLoad() { - super.viewDidLoad() + super.viewDidLoad() + localVideoDraggable?.respectedView = localVideoContainer + } + + @objc func click(gesture:UIGestureRecognizer){ + gesture.view?.removeFromSuperview() + } + + @IBAction func btnOnScreenTapped(_ sender: Any) { + if(hideVideoBtn.isSelected){ + circleFloatBtnTapped(hideVideoBtn) + + }else if(btnMinimize.isSelected){ + btnMinimizeTapped(btnMinimize) + } + } + + @IBAction func btnSwipeVideoTapped(_ sender: Any) { +// let smallVdoRender = smallVideoView.subviews.first +// let fullVdoRender = fullVideoView.subviews.first +// if let vdo = smallVdoRender{ +// fullVideoView.addSubview(vdo) +// } +// if let vdo = fullVdoRender{ +// smallVideoView.addSubview(vdo) +// } +// +// layoutVideoRenderViews() + } + + @IBAction func didClickMuteButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + publisher!.publishAudio = !sender.isSelected + } + + @IBAction func didClickSpeakerButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + subscriber?.subscribeToAudio = !sender.isSelected + } + + @IBAction func didClickVideoMuteButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + if publisher!.publishVideo { + publisher!.publishVideo = false + } else { + publisher!.publishVideo = true + } + smallVideoView.isHidden = sender.isSelected + localVideoMutedBg.isHidden = !sender.isSelected + + } + + + @IBAction func didClickSwitchCameraButton(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + if sender.isSelected { + publisher!.cameraPosition = AVCaptureDevice.Position.front + } else { + publisher!.cameraPosition = AVCaptureDevice.Position.back + } + } + + @IBAction func hangUp(_ sender: UIButton) { + callBack?.sessionDone(res:["callResponse":"CallEnd"]) + sessionDisconnect() + } + + @IBAction func circleFloatBtnTapped(_ sender: UIButton) { + sender.isSelected = !sender.isSelected + onCircleFloat?(sender.isSelected) + topBar.isHidden = sender.isSelected + controlButtons.isHidden = sender.isSelected + smallVideoView.isHidden = sender.isSelected + self.publisher?.view?.layoutIfNeeded() + } + + @IBAction func btnMinimizeTapped(_ sender: UIButton) { + minimizeVideoState(state: !sender.isSelected) + btnScreenTap.isHidden = !sender.isSelected + } + + func minimizeVideoState(state:Bool){ + btnMinimize.isSelected = state + onRectFloat?(state) - setupButtons() - askForMicrophonePermission() - requestCameraPermissionsIfNeeded() - hideVideoMuted() - setupSession() - - } + NSLayoutConstraint.activate(state ? minimizeConstraint : maximisedConstraint) + NSLayoutConstraint.deactivate(state ? maximisedConstraint : minimizeConstraint) + localVideoDraggable?.enable(!state) + + lblRemoteUsername.isHidden = state + hideVideoBtn.isHidden = !state + lblCallDuration.superview?.isHidden = !hideVideoBtn.isHidden + + UIView.animate(withDuration: 0.5) { + self.videoMuteBtn.isHidden = state + self.micMuteBtn.isHidden = state + self.camSwitchBtn.isHidden = state + self.layoutVideoRenderViews() + } + } + func layoutVideoRenderViews(){ + if let publisherVdoSize = publisher?.view?.superview?.bounds.size{ + publisher?.view?.frame = CGRect(x: 0, y: 0, width: publisherVdoSize.width, height: publisherVdoSize.height) + } + if let subscriberVdoSize = subscriber?.view?.superview?.bounds.size{ + subscriber?.view?.frame = CGRect(x: 0, y: 0, width: subscriberVdoSize.width, height: subscriberVdoSize.height) + } + } + + var durationTimer:Timer?; + func startUpdateCallDuration(){ + var seconds = 0 + durationTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in + seconds = seconds+1 + let durationSegments = (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60) + let hours = String(format: "%02d", durationSegments.0) + let mins = String(format: "%02d", durationSegments.1) + let secs = String(format: "%02d", durationSegments.2) + let durationString = "\(mins):\(secs)" + + self.lblCallDuration.text = durationString + } + } + + func start(params:VideoCallRequestParameters){ + lblRemoteUsername.text = params.patientName ?? "- - -" + btnScreenTap.isHidden = true + hideVideoBtn.isHidden = true + + self.kApiKey = params.apiKey ?? "" + self.kSessionId = params.sessionId ?? "" + self.kToken = params.token ?? "" + self.VC_ID = params.vcId ?? 0 + self.generalid = params.generalId ?? "" + self.TokenID = params.tokenId ?? "" + self.DoctorId = params.doctorId ?? 0 + self.baseUrl = params.baseUrl ?? "" + + askForMicrophonePermission() + requestCameraPermissionsIfNeeded() + hideVideoMuted() + setupSession() + + } private func changeCallStatus(callStatus:Int){ let URL_USER_REGISTER = baseUrl+"LiveCareApi/DoctorApp/ChangeCallStatus" @@ -107,13 +277,6 @@ class ViewController: UIViewController { } } - - func setupButtons() { - perform(#selector(hideControlButtons), with: nil, afterDelay: 3) - let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:))) - view.addGestureRecognizer(tapGestureRecognizer) - view.isUserInteractionEnabled = true - } // MARK: -Microphone Camera and Permission Request func askForMicrophonePermission() { @@ -137,59 +300,16 @@ class ViewController: UIViewController { // display a useful message asking the user to grant permissions from within Settings > Privacy > Camera } - - @IBAction func didClickMuteButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - publisher!.publishAudio = !sender.isSelected - - } - - @IBAction func didClickSpeakerButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - subscriber?.subscribeToAudio = !sender.isSelected - // resetHideButtonsTimer() - } - - @IBAction func didClickVideoMuteButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - if publisher!.publishVideo { - publisher!.publishVideo = false - } else { - publisher!.publishVideo = true - } - localVideo.isHidden = sender.isSelected - localVideoMutedBg.isHidden = !sender.isSelected - localVideoMutedIndicator.isHidden = !sender.isSelected - // resetHideButtonsTimer() - - } - - - @IBAction func didClickSwitchCameraButton(_ sender: UIButton) { - sender.isSelected = !sender.isSelected - if sender.isSelected { - publisher!.cameraPosition = AVCaptureDevice.Position.front - } else { - publisher!.cameraPosition = AVCaptureDevice.Position.back - } - /// resetHideButtonsTimer() - } - - @IBAction func hangUp(_ sender: UIButton) { - callBack?.sessionDone(res:["callResponse":"CallEnd"]) - sessionDisconnect() - } - - func sessionDisconnect() { changeCallStatus(callStatus: 16) if (session != nil) { print("disconnecting....") session!.disconnect(nil) dismiss(animated: true) - return } dismiss(animated: true) + onCallDisconnect?() + durationTimer?.invalidate() } func requestCameraPermissionsIfNeeded() { @@ -226,7 +346,6 @@ class ViewController: UIViewController { func hideVideoMuted() { remoteVideoMutedIndicator.isHidden = true localVideoMutedBg.isHidden = true - localVideoMutedIndicator.isHidden = true } func setupSession() { @@ -267,19 +386,6 @@ class ViewController: UIViewController { - @IBOutlet weak var localVideo: UIView! - - @IBOutlet weak var remoteVideo: UIView! - - @IBOutlet weak var controlButtons: UIView! - - @IBOutlet weak var remoteVideoMutedIndicator: UIImageView! - - @IBOutlet weak var localVideoMutedBg: UIImageView! - - - @IBOutlet weak var localVideoMutedIndicator: UIImageView! - @objc func updateTimer(){ seconds -= 1 //This will decrement(count down)the seconds. print(seconds) @@ -293,17 +399,11 @@ class ViewController: UIViewController { } -extension ViewController: OTSessionDelegate { +extension VideoCallViewController: OTSessionDelegate { func sessionDidConnect(_ session: OTSession) { - print("The client connected to the OpenTok session.") - - - - - timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true) - - + print("The client connected to the OpenTok session.") + timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(VideoCallViewController.updateTimer)), userInfo: nil, repeats: true) setupPublisher() } @@ -318,10 +418,12 @@ extension ViewController: OTSessionDelegate { if error != nil { showAlert(error?.localizedDescription) } - - publisher?.view!.frame = CGRect(x: localVideo.bounds.origin.x, y: localVideo.bounds.origin.y, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height) - - localVideo.addSubview((publisher?.view)!) + + publisher?.view?.tag = 11 + publisher?.view?.layer.cornerRadius = 5 + publisher?.view?.clipsToBounds = true + smallVideoView.addSubview((publisher?.view)!) + layoutVideoRenderViews() } func sessionDidDisconnect(_ session: OTSession) { @@ -346,27 +448,27 @@ extension ViewController: OTSessionDelegate { func session(_ session: OTSession, streamCreated stream: OTStream) { - subscriber = OTSubscriber(stream: stream, delegate: self) - guard let subscriber = subscriber else { - return - } + subscriber = OTSubscriber(stream: stream, delegate: self) + guard let subscriber = subscriber else { + return + } - var error: OTError? - session.subscribe(subscriber, error: &error) - guard error == nil else { - print(error!) - return - } + var error: OTError? + session.subscribe(subscriber, error: &error) + guard error == nil else { + print(error!) + return + } - guard let subscriberView = subscriber.view else { - return - } - subscriberView.frame = UIScreen.main.bounds - view.insertSubview(subscriberView, at: 0) + guard let subscriberView = subscriber.view else { + return + } + subscriberView.tag = 22 + fullVideoView.addSubview(subscriberView) + layoutVideoRenderViews() -// if nil == subscriber { -// setupSubscribe(stream) -// } + startUpdateCallDuration() + onCallConnect?() } func setupSubscribe(_ stream: OTStream?) { @@ -408,19 +510,13 @@ extension ViewController: OTSessionDelegate { } -extension ViewController: OTPublisherDelegate { +extension VideoCallViewController: OTPublisherDelegate { func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) { print("The publisher failed: \(error)") } - @objc func remoteVideoTapped(_ recognizer: UITapGestureRecognizer?) { - if controlButtons.isHidden { - controlButtons.isHidden = false - perform(#selector(hideControlButtons), with: nil, afterDelay: 3) - } - } } -extension ViewController: OTSubscriberDelegate { +extension VideoCallViewController: OTSubscriberDelegate { public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) { print("The subscriber did connect to the stream.") } @@ -428,8 +524,5 @@ extension ViewController: OTSubscriberDelegate { public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) { print("The subscriber failed to connect to the stream.") } - @objc func hideControlButtons() { - controlButtons.isHidden = true - } } diff --git a/lib/client/base_app_client.dart b/lib/client/base_app_client.dart index bba61c2a..00069e3a 100644 --- a/lib/client/base_app_client.dart +++ b/lib/client/base_app_client.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/NavigationService.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; @@ -12,6 +13,9 @@ import 'package:flutter/cupertino.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; +import '../locator.dart'; +import '../routes.dart'; + DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = new Helpers(); @@ -101,12 +105,13 @@ class BaseAppClient { helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'], parsed['AndroidLink'], parsed['IOSLink']); } - if (!parsed['IsAuthenticated']) { + if (parsed['IsAuthenticated'] != null && !parsed['IsAuthenticated']) { if (body['OTP_SendType'] != null) { onFailure(getError(parsed), statusCode); } else if (!isAllowAny) { await Provider.of(AppGlobal.CONTEX, listen: false).logout(); Helpers.showErrorToast('Your session expired Please login again'); + locator().pushNamedAndRemoveUntil(ROOT); } if (isAllowAny) { onFailure(getError(parsed), statusCode); diff --git a/lib/config/config.dart b/lib/config/config.dart index 0283577e..eb361798 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -56,6 +56,8 @@ const ADD_REFERRED_DOCTOR_REMARKS = 'Services/DoctorApplication.svc/REST/AddRefe const GET_MY_REFERRED_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredPatient'; +const GET_MY_REFERRED_OUT_PATIENT = 'Services/DoctorApplication.svc/REST/GtMyReferredOutPatient'; + const GET_PENDING_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/PendingReferrals'; const CREATE_REFERRAL_PATIENT = 'Services/DoctorApplication.svc/REST/CreateReferral'; @@ -89,6 +91,8 @@ const CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RES const GET_DOC_PROFILES = 'Services/Doctors.svc/REST/GetDocProfiles'; const TRANSFERT_TO_ADMIN = 'LiveCareApi/DoctorApp/TransferToAdmin'; +const SEND_SMS_INSTRUCTIONS = 'LiveCareApi/DoctorApp/SendSMSInstruction'; +const GET_ALTERNATIVE_SERVICE = 'LiveCareApi/DoctorApp/GetAlternativeServices'; const END_CALL = 'LiveCareApi/DoctorApp/EndCall'; const END_CALL_WITH_CHARGE = 'LiveCareApi/DoctorApp/CompleteCallWithCharge'; const GET_DASHBOARD = 'Services/DoctorApplication.svc/REST/GetDoctorDashboardKPI'; @@ -177,6 +181,8 @@ const GET_ECG = "Services/Patients.svc/REST/HIS_GetPatientMuseResults"; const GET_MY_REFERRAL_INPATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralPatient"; +const GET_MY_REFERRAL_OUT_PATIENT = "Services/DoctorApplication.svc/REST/GtMyReferralForOutPatient"; + const GET_MY_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargeReferralPatient"; const GET_DISCHARGE_PATIENT = "Services/DoctorApplication.svc/REST/GtMyDischargePatient"; @@ -217,6 +223,11 @@ const GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP = 'Services/DoctorApplication.svc/RE const DOCTOR_CHECK_HAS_LIVE_CARE = "Services/DoctorApplication.svc/REST/CheckDoctorHasLiveCare"; +const LIVE_CARE_IS_LOGIN = "LiveCareApi/DoctorApp/UseIsLogin"; +const ADD_REFERRED_REMARKS_NEW = "Services/DoctorApplication.svc/REST/AddReferredDoctorRemarks_New"; +const GET_SPECIAL_CLINICAL_CARE_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareList"; +const GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST = "Services/DoctorApplication.svc/REST/GetSpecialClinicalCareMappingList"; + var selectedPatientType = 1; //*********change value to decode json from Dropdown ************ diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 231e7f9b..270907be 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -568,7 +568,7 @@ const Map> localizedValues = { 'ar': "ليس هناك شكوى رئيس" }, "more-verify": { - "en": "More Verification Options", + "en": "More Verification \n Options", "ar": "المزيد من خيارات التحقق" }, "welcome-back": {"en": "Welcome back!", "ar": "مرحبا بعودتك!"}, @@ -651,6 +651,10 @@ const Map> localizedValues = { 'en': "add Selected Procedures", 'ar': "اضافة العمليات المختارة " }, + 'addProcedures': { + 'en': "Add Procedure", + 'ar': "اضافة العمليات" + }, 'updateProcedure': {'en': "Update Procedure", 'ar': "تحديث العملية"}, 'orderProcedure': {'en': "order procedure", 'ar': "طلب العمليات"}, 'nameOrICD': {'en': "Name or ICD", 'ar': "الاسم او  ICD"}, @@ -708,7 +712,7 @@ const Map> localizedValues = { 'days': {'en': "Days", 'ar': "أيام"}, 'months': {'en': "Months", 'ar': "أشهر"}, 'years': {'en': "Years", 'ar': "سنين"}, - 'hr': {'en': "HR", 'ar': "س"}, + 'hr': {'en': "Hr", 'ar': "س"}, 'min': {'en': "Min", 'ar': "د"}, 'appointmentNumber': {'en': "Appointment Number", 'ar': "رقم الموعد"}, 'referralStatusHold': {'en': "Hold", 'ar': "معلق"}, @@ -998,4 +1002,12 @@ const Map> localizedValues = { "onHold": {"en": "On Hold", "ar": "قيد الانتظار"}, "verified": {"en": "Verified", "ar": "تم التحقق"}, "endCall": {"en": "End Call", "ar": "انهاء"}, + "favoriteTemplates": {"en": "Favorite Templates", "ar": "القوالب المفضلة"}, + "allProcedures": {"en": "All Procedures", "ar": "جميع الإجراءات"}, + "allRadiology": {"en": "All Radiology", "ar": "جميع الأشعة"}, + "allLab": {"en": "All Lab", "ar": "جميع المختبرات"}, + "allPrescription": {"en": "All Prescription", "ar": "جميع الوصفات"}, + "addPrescription": {"en": "Add prescription", "ar": "إضافة الوصفات"}, + "edit": {"en": "Edit", "ar": "تعديل"}, + "summeryReply": {"en": "Summary Reply", "ar": "موجز الرد"}, }; diff --git a/lib/config/size_config.dart b/lib/config/size_config.dart index e4b1e745..8a9c7ac6 100644 --- a/lib/config/size_config.dart +++ b/lib/config/size_config.dart @@ -17,6 +17,11 @@ class SizeConfig { static bool isPortrait = true; static bool isMobilePortrait = false; static bool isMobile = false; + static bool isHeightShort = false; + static bool isHeightVeryShort = false; + static bool isHeightMiddle = false; + static bool isHeightLarge = false; + static bool isWidthLarge = false; void init(BoxConstraints constraints, Orientation orientation) { realScreenHeight = constraints.maxHeight; @@ -25,20 +30,30 @@ class SizeConfig { if (constraints.maxWidth <= MAX_SMALL_SCREEN) { isMobile = true; } + if (constraints.maxHeight < 600) { + isHeightVeryShort = true; + } else if (constraints.maxHeight < 800) { + isHeightShort = true; + } else if (constraints.maxHeight < 1000) { + isHeightMiddle = true; + } else { + isHeightLarge = true; + } + + if(constraints.maxWidth > 600) { + isWidthLarge = true; + } + if (orientation == Orientation.portrait) { isPortrait = true; if (realScreenWidth! < 450) { isMobilePortrait = true; } - // textMultiplier = _blockHeight; - // imageSizeMultiplier = _blockWidth; screenHeight = realScreenHeight; screenWidth = realScreenWidth; } else { isPortrait = false; isMobilePortrait = false; - // textMultiplier = _blockWidth; - // imageSizeMultiplier = _blockHeight; screenHeight = realScreenWidth; screenWidth = realScreenHeight; } @@ -59,4 +74,29 @@ class SizeConfig { print('isPortrait $isPortrait'); print('isMobilePortrait $isMobilePortrait'); } + + static getTextMultiplierBasedOnWidth({double width}){ + // TODO handel LandScape case + if(width != null) { + return width / 100; + } + return widthMultiplier; + } + + + static getWidthMultiplier({double width}){ + // TODO handel LandScape case + if(width != null) { + return width / 100; + } + return widthMultiplier; + } + + static getHeightMultiplier({double height}){ + // TODO handel LandScape case + if(height != null) { + return height / 100; + } + return heightMultiplier; + } } diff --git a/lib/core/enum/PatientType.dart b/lib/core/enum/PatientType.dart new file mode 100644 index 00000000..96fd9ae5 --- /dev/null +++ b/lib/core/enum/PatientType.dart @@ -0,0 +1,4 @@ +enum PatientType{ + IN_PATIENT, + OUT_PATIENT, +} \ No newline at end of file diff --git a/lib/core/model/live_care/AlternativeServicesList.dart b/lib/core/model/live_care/AlternativeServicesList.dart new file mode 100644 index 00000000..11f27b95 --- /dev/null +++ b/lib/core/model/live_care/AlternativeServicesList.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; + +class AlternativeService { + int serviceID; + String serviceName; + bool isSelected; + + AlternativeService( + {this.serviceID, this.serviceName, this.isSelected = false}); + + AlternativeService.fromJson(Map json) { + serviceID = json['ServicID']; + serviceName = json['ServiceName']; + isSelected = false; + } + + Map toJson() { + final Map data = new Map(); + data['ServicID'] = this.serviceID; + data['ServiceName'] = this.serviceName; + return data; + } +} + +class AlternativeServicesList with ChangeNotifier { + List _alternativeServicesList; + + getServicesList(){ + return _alternativeServicesList; + } + + setServicesList(List alternativeServicesList) { + this._alternativeServicesList = alternativeServicesList; + notifyListeners(); + } + + setSelected(AlternativeService service, bool isSelected) { + List alternativeService = _alternativeServicesList.where((element) => service.serviceID == element.serviceID).toList(); + + alternativeService[0].isSelected = isSelected; + notifyListeners(); + } +} diff --git a/lib/core/model/live_care/live_care_login_reguest_model.dart b/lib/core/model/live_care/live_care_login_reguest_model.dart new file mode 100644 index 00000000..e14d4223 --- /dev/null +++ b/lib/core/model/live_care/live_care_login_reguest_model.dart @@ -0,0 +1,27 @@ +class LiveCareUserLoginRequestModel { + String tokenID; + String generalid; + int doctorId; + int isOutKsa; + int isLogin; + + LiveCareUserLoginRequestModel({this.tokenID, this.generalid, this.doctorId, this.isOutKsa, this.isLogin}); + + LiveCareUserLoginRequestModel.fromJson(Map json) { + tokenID = json['TokenID']; + generalid = json['generalid']; + doctorId = json['DoctorId']; + isOutKsa = json['IsOutKsa']; + isLogin = json['IsLogin']; + } + + Map toJson() { + final Map data = new Map(); + data['TokenID'] = this.tokenID; + data['generalid'] = this.generalid; + data['DoctorId'] = this.doctorId; + data['IsOutKsa'] = this.isOutKsa; + data['IsLogin'] = this.isLogin; + return data; + } +} diff --git a/lib/core/model/patient_muse/PatientSearchRequestModel.dart b/lib/core/model/patient_muse/PatientSearchRequestModel.dart index 3a722c96..7117382c 100644 --- a/lib/core/model/patient_muse/PatientSearchRequestModel.dart +++ b/lib/core/model/patient_muse/PatientSearchRequestModel.dart @@ -11,20 +11,24 @@ class PatientSearchRequestModel { int ?searchType; String? mobileNo; String? identificationNo; + int nursingStationID; + int clinicID=0; PatientSearchRequestModel( - {this.doctorID =0, - this.firstName ="0", - this.middleName ="0", - this.lastName ="0", - this.patientMobileNumber ="0", - this.patientIdentificationID ="0", - this.patientID =0, - this.searchType =1, - this.mobileNo="", - this.identificationNo="0", - this.from ="0", - this.to ="0"}); + {this.doctorID = 0, + this.firstName = "0", + this.middleName = "0", + this.lastName = "0", + this.patientMobileNumber = "0", + this.patientIdentificationID = "0", + this.patientID = 0, + this.searchType = 1, + this.mobileNo = "", + this.identificationNo = "0", + this.from = "0", + this.to = "0", + this.clinicID, + this.nursingStationID = 0}); PatientSearchRequestModel.fromJson(Map json) { doctorID = json['DoctorID']; @@ -39,6 +43,8 @@ class PatientSearchRequestModel { searchType = json['SearchType']; mobileNo = json['MobileNo']; identificationNo = json['IdentificationNo']; + nursingStationID = json['NursingStationID']; + clinicID = json['ClinicID']; } Map toJson() { @@ -55,6 +61,9 @@ class PatientSearchRequestModel { data['SearchType'] = this.searchType; data['MobileNo'] = this.mobileNo; data['IdentificationNo'] = this.identificationNo; + data['NursingStationID'] = this.nursingStationID; + data['ClinicID'] = this.clinicID; + data['ProjectID'] = 0; return data; } } diff --git a/lib/core/model/referral/MyReferralPatientModel.dart b/lib/core/model/referral/MyReferralPatientModel.dart index 87757148..ec1f7758 100644 --- a/lib/core/model/referral/MyReferralPatientModel.dart +++ b/lib/core/model/referral/MyReferralPatientModel.dart @@ -61,71 +61,74 @@ class MyReferralPatientModel { String? priorityDescription; String? referringClinicDescription; String? referringDoctorName; + int referalStatus; MyReferralPatientModel( {this.rowID, - this.projectID, - this.lineItemNo, - this.doctorID, - this.patientID, - this.doctorName, - this.doctorNameN, - this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, - this.gender, - this.dateofBirth, - this.mobileNumber, - this.emailAddress, - this.patientIdentificationNo, - this.patientType, - this.admissionNo, - this.admissionDate, - this.roomID, - this.bedID, - this.nursingStationID, - this.description, - this.nationalityName, - this.nationalityNameN, - this.clinicDescription, - this.clinicDescriptionN, - this.referralDoctor, - this.referringDoctor, - this.referralClinic, - this.referringClinic, - this.referralStatus, - this.referralDate, - this.referringDoctorRemarks, - this.referredDoctorRemarks, - this.referralResponseOn, - this.priority, - this.frequency, - this.mAXResponseTime, - this.episodeID, - this.appointmentNo, - this.appointmentDate, - this.appointmentType, - this.patientMRN, - this.createdOn, - this.clinicID, - this.nationalityID, - this.age, - this.doctorImageURL, - this.frequencyDescription, - this.genderDescription, - this.isDoctorLate, - this.isDoctorResponse, - this.nationalityFlagURL, - this.nursingStationName, - this.priorityDescription, - this.referringClinicDescription, - this.referringDoctorName}); + this.projectID, + this.lineItemNo, + this.doctorID, + this.patientID, + this.doctorName, + this.doctorNameN, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.gender, + this.dateofBirth, + this.mobileNumber, + this.emailAddress, + this.patientIdentificationNo, + this.patientType, + this.admissionNo, + this.admissionDate, + this.roomID, + this.bedID, + this.nursingStationID, + this.description, + this.nationalityName, + this.nationalityNameN, + this.clinicDescription, + this.clinicDescriptionN, + this.referralDoctor, + this.referringDoctor, + this.referralClinic, + this.referringClinic, + this.referralStatus, + this.referralDate, + this.referringDoctorRemarks, + this.referredDoctorRemarks, + this.referralResponseOn, + this.priority, + this.frequency, + this.mAXResponseTime, + this.episodeID, + this.appointmentNo, + this.appointmentDate, + this.appointmentType, + this.patientMRN, + this.createdOn, + this.clinicID, + this.nationalityID, + this.age, + this.doctorImageURL, + this.frequencyDescription, + this.genderDescription, + this.isDoctorLate, + this.isDoctorResponse, + this.nationalityFlagURL, + this.nursingStationName, + this.priorityDescription, + this.referringClinicDescription, + this.referringDoctorName, + this.referalStatus}); MyReferralPatientModel.fromJson(Map json) { rowID = json['RowID']; + referalStatus = json['ReferalStatus']; projectID = json['ProjectID']; lineItemNo = json['LineItemNo']; doctorID = json['DoctorID']; @@ -158,8 +161,21 @@ class MyReferralPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json['ReferralStatus']; - referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + referralStatus = json["ReferralStatus"] is String + ? json['ReferralStatus'] == "Accepted" + ? 46 + : json['ReferralStatus'] == "Pending" + ? 1 + : 0 + : json["ReferralStatus"]; + try { + referralDate = AppDateUtils.getDateTimeFromString(json['ReferralDate']); + } catch (e) { + referralDate = AppDateUtils.convertStringToDate(json['ReferralDate']); + } finally { + referralDate = DateTime.now(); + } + referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; @@ -190,6 +206,7 @@ class MyReferralPatientModel { Map toJson() { final Map data = new Map(); data['RowID'] = this.rowID; + data['ReferalStatus'] = this.referalStatus; data['ProjectID'] = this.projectID; data['LineItemNo'] = this.lineItemNo; data['DoctorID'] = this.doctorID; @@ -253,6 +270,6 @@ class MyReferralPatientModel { } get patientName { - return this.firstName!+" "+this.lastName!; + return this.firstName !+ " " + this.lastName!; } } diff --git a/lib/core/model/referral/MyReferralPatientRequestModel.dart b/lib/core/model/referral/MyReferralPatientRequestModel.dart new file mode 100644 index 00000000..08b98a99 --- /dev/null +++ b/lib/core/model/referral/MyReferralPatientRequestModel.dart @@ -0,0 +1,104 @@ +class MyReferralPatientRequestModel { + int channel; + int clinicID; + int doctorID; + int editedBy; + String firstName; + String from; + String iPAdress; + bool isLoginForDoctorApp; + int languageID; + String lastName; + String middleName; + int patientID; + String patientIdentificationID; + String patientMobileNumber; + bool patientOutSA; + int patientTypeID; + int projectID; + String sessionID; + String stamp; + String to; + String tokenID; + double versionID; + String vidaAuthTokenID; + + MyReferralPatientRequestModel( + {this.channel, + this.clinicID, + this.doctorID, + this.editedBy, + this.firstName, + this.from, + this.iPAdress, + this.isLoginForDoctorApp, + this.languageID, + this.lastName, + this.middleName, + this.patientID, + this.patientIdentificationID, + this.patientMobileNumber, + this.patientOutSA, + this.patientTypeID, + this.projectID, + this.sessionID, + this.stamp, + this.to, + this.tokenID, + this.versionID, + this.vidaAuthTokenID}); + + MyReferralPatientRequestModel.fromJson(Map json) { + channel = json['Channel']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + editedBy = json['EditedBy']; + firstName = json['FirstName']; + from = json['From']; + iPAdress = json['IPAdress']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + languageID = json['LanguageID']; + lastName = json['LastName']; + middleName = json['MiddleName']; + patientID = json['PatientID']; + patientIdentificationID = json['PatientIdentificationID']; + patientMobileNumber = json['PatientMobileNumber']; + patientOutSA = json['PatientOutSA']; + patientTypeID = json['PatientTypeID']; + projectID = json['ProjectID']; + sessionID = json['SessionID']; + stamp = json['stamp']; + to = json['To']; + tokenID = json['TokenID']; + versionID = json['VersionID']; + vidaAuthTokenID = json['VidaAuthTokenID']; + } + + Map toJson() { + final Map data = new Map(); + data['Channel'] = this.channel; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['EditedBy'] = this.editedBy; + data['FirstName'] = this.firstName; + data['From'] = this.from; + data['IPAdress'] = this.iPAdress; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['LanguageID'] = this.languageID; + data['LastName'] = this.lastName; + data['MiddleName'] = this.middleName; + data['PatientID'] = this.patientID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientOutSA'] = this.patientOutSA; + data['PatientTypeID'] = this.patientTypeID; + data['ProjectID'] = this.projectID; + data['SessionID'] = this.sessionID; + data['stamp'] = this.stamp; + data['To'] = this.to; + data['TokenID'] = this.tokenID; + data['VersionID'] = this.versionID; + data['VidaAuthTokenID'] = this.vidaAuthTokenID; + return data; + } +} diff --git a/lib/core/model/referral/add_referred_remarks_request.dart b/lib/core/model/referral/add_referred_remarks_request.dart new file mode 100644 index 00000000..14089513 --- /dev/null +++ b/lib/core/model/referral/add_referred_remarks_request.dart @@ -0,0 +1,72 @@ +class AddReferredRemarksRequestModel { + int projectID; + int admissionNo; + int lineItemNo; + String referredDoctorRemarks; + int editedBy; + int referalStatus; + bool isLoginForDoctorApp; + String iPAdress; + bool patientOutSA; + String tokenID; + int languageID; + double versionID; + int channel; + String sessionID; + int deviceTypeID; + + AddReferredRemarksRequestModel( + {this.projectID, + this.admissionNo, + this.lineItemNo, + this.referredDoctorRemarks, + this.editedBy, + this.referalStatus, + this.isLoginForDoctorApp, + this.iPAdress, + this.patientOutSA, + this.tokenID, + this.languageID, + this.versionID, + this.channel, + this.sessionID, + this.deviceTypeID}); + + AddReferredRemarksRequestModel.fromJson(Map json) { + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + lineItemNo = json['LineItemNo']; + referredDoctorRemarks = json['ReferredDoctorRemarks']; + editedBy = json['EditedBy']; + referalStatus = json['ReferalStatus']; + isLoginForDoctorApp = json['IsLoginForDoctorApp']; + iPAdress = json['IPAdress']; + patientOutSA = json['PatientOutSA']; + tokenID = json['TokenID']; + languageID = json['LanguageID']; + versionID = json['VersionID']; + channel = json['Channel']; + sessionID = json['SessionID']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['LineItemNo'] = this.lineItemNo; + data['ReferredDoctorRemarks'] = this.referredDoctorRemarks; + data['EditedBy'] = this.editedBy; + data['ReferalStatus'] = this.referalStatus; + data['IsLoginForDoctorApp'] = this.isLoginForDoctorApp; + data['IPAdress'] = this.iPAdress; + data['PatientOutSA'] = this.patientOutSA; + data['TokenID'] = this.tokenID; + data['LanguageID'] = this.languageID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['SessionID'] = this.sessionID; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/service/NavigationService.dart b/lib/core/service/NavigationService.dart new file mode 100644 index 00000000..26191ffc --- /dev/null +++ b/lib/core/service/NavigationService.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +class NavigationService { + final GlobalKey navigatorKey = + new GlobalKey(); + Future navigateTo(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushNamed(routeName,arguments: arguments); + } + + Future pushReplacementNamed(String routeName,{Object arguments}) { + return navigatorKey.currentState.pushReplacementNamed(routeName,arguments: arguments); + } + + + Future pushNamedAndRemoveUntil(String routeName) { + return navigatorKey.currentState.pushNamedAndRemoveUntil(routeName,(asd)=>false); + } +} \ No newline at end of file diff --git a/lib/core/service/VideoCallService.dart b/lib/core/service/VideoCallService.dart new file mode 100644 index 00000000..f72544a0 --- /dev/null +++ b/lib/core/service/VideoCallService.dart @@ -0,0 +1,89 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; +import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; +import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; +import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; +import 'package:doctor_app_flutter/models/livecare/start_call_res.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/VideoChannel.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; + +import '../../locator.dart'; +import '../../routes.dart'; +import 'NavigationService.dart'; + +class VideoCallService extends BaseService{ + + StartCallRes startCallRes; + PatiantInformtion patient; + LiveCarePatientServices _liveCarePatientServices = locator(); + + openVideo(StartCallRes startModel,PatiantInformtion patientModel,VoidCallback onCallConnected, VoidCallback onCallDisconnected)async{ + this.startCallRes = startModel; + this.patient = patientModel; + DoctorProfileModel doctorProfile = await getDoctorProfile(isGetProfile: true); + await VideoChannel.openVideoCallScreen( + kToken: startCallRes.openTokenID,//"T1==cGFydG5lcl9pZD00NzI0Nzk1NCZzaWc9NGIyZDljOTY3YjFiNWU1YzUzNzFmMjIyNjJmNmEzY2Y5NzZjOTdlYzpzZXNzaW9uX2lkPTFfTVg0ME56STBOemsxTkg1LU1UWXlNekEyTlRRMU9EVXhObjVrVFRoMFlVdFJXaXRYTWpadFZGZHFhSGxZVGpOdE1UVi1mZyZjcmVhdGVfdGltZT0xNjIzMDY1NDk1Jm5vbmNlPTAuMjM2Mjk0NTIwMTkyOTA4OTcmcm9sZT1wdWJsaXNoZXImZXhwaXJlX3RpbWU9MTYyNTY1NzQ5NCZpbml0aWFsX2xheW91dF9jbGFzc19saXN0PQ==", + kSessionId:startCallRes.openSessionID,//1_MX40NzI0Nzk1NH5-MTYyMzA2NTQ1ODUxNn5kTTh0YUtRWitXMjZtVFdqaHlYTjNtMTV-fg + kApiKey: '46209962',//'47247954' + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), + tokenID: await sharedPref.getString(TOKEN), + generalId: GENERAL_ID, + doctorId: doctorProfile.doctorID, + onFailure: (String error) { + DrAppToastMsg.showErrorToast(error); + },onCallConnected: onCallConnected, + onCallEnd: () { + WidgetsBinding.instance.addPostFrameCallback((_) async { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, false,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + }else + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + + }); + }); + }, + onCallNotRespond: (SessionStatusModel sessionStatusModel) { + WidgetsBinding.instance.addPostFrameCallback((_) { + GifLoaderDialogUtils.showMyDialog(locator().navigatorKey.currentContext); + endCall(patient.vcId, sessionStatusModel.sessionStatus == 3,).then((value) { + GifLoaderDialogUtils.hideDialog(locator().navigatorKey.currentContext); + if (hasError) { + DrAppToastMsg.showErrorToast(error); + } else { + locator().navigateTo(PATIENTS_END_Call,arguments: { + "patient": patient, + }); + } + + }); + + }); + }); + + } + Future endCall(int vCID, bool isPatient) async { + hasError = false; + await getDoctorProfile(isGetProfile: true); + EndCallReq endCallReq = new EndCallReq(); + endCallReq.doctorId = doctorProfile.doctorID; + endCallReq.generalid = 'Cs2020@2016\$2958'; + endCallReq.vCID = vCID; + endCallReq.isDestroy = isPatient; + await _liveCarePatientServices.endCall(endCallReq); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + } + } + +} \ No newline at end of file diff --git a/lib/core/service/home/dasboard_service.dart b/lib/core/service/home/dasboard_service.dart index 401ec76e..5516923a 100644 --- a/lib/core/service/home/dasboard_service.dart +++ b/lib/core/service/home/dasboard_service.dart @@ -1,10 +1,12 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; class DashboardService extends BaseService { List _dashboardItemsList = []; List get dashboardItemsList => _dashboardItemsList; + bool hasVirtualClinic = false; String ?sServiceID; @@ -24,8 +26,6 @@ class DashboardService extends BaseService { super.error = error; }, body: { - // "VidaAuthTokenID": - // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyODA0IiwianRpIjoiZDYxZmM5MTQtZWFhYy00YjQ4LTgyMmEtMmE3OTNlZDMzZGYwIiwiZW1haWwiOiJNb2hhbWVkLlJlc3dhbkBjbG91ZHNvbHV0aW9uLXNhLmNvbSIsImlkIjoiMjgwNCIsIk5hbWUiOiJNVUhBTU1BRCBBWkFNIiwiRW1wbG95ZWVJZCI6IjE0ODUiLCJGYWNpbGl0eUdyb3VwSWQiOiIwMTAyNjYiLCJGYWNpbGl0eUlkIjoiMTUiLCJQaGFyYW1jeUZhY2lsaXR5SWQiOiI1NSIsIklTX1BIQVJNQUNZX0NPTk5FQ1RFRCI6IlRydWUiLCJEb2N0b3JJZCI6IjE0ODUiLCJTRVNTSU9OSUQiOiIyMTU3NTgwOCIsIkNsaW5pY0lkIjoiMyIsInJvbGUiOlsiU0VDVVJJVFkgQURNSU5JU1RSQVRPUlMiLCJTRVRVUCBBRE1JTklTVFJBVE9SUyIsIkNFTydTIiwiRVhFQ1VUSVZFIERJUkVDVE9SUyIsIk1BTkFHRVJTIiwiU1VQRVJWSVNPUlMiLCJDTElFTlQgU0VSVklDRVMgQ09PUkRJTkFUT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIFNVUEVSVklTT1JTIiwiQ0xJRU5UIFNFUlZJQ0VTIE1BTkdFUlMiLCJIRUFEIE5VUlNFUyIsIkRPQ1RPUlMiLCJDSElFRiBPRiBNRURJQ0FMIFNUQUZGUyIsIkJJTy1NRURJQ0FMIFRFQ0hOSUNJQU5TIiwiQklPLU1FRElDQUwgRU5HSU5FRVJTIiwiQklPLU1FRElDQUwgREVQQVJUTUVOVCBIRUFEUyIsIklUIEhFTFAgREVTSyIsIkFETUlOSVNUUkFUT1JTIiwiTEFCIEFETUlOSVNUUkFUT1IiLCJMQUIgVEVDSE5JQ0lBTiIsIkJVU0lORVNTIE9GRklDRSBTVEFGRiIsIkZJTkFOQ0UgQUNDT1VOVEFOVFMiLCJQSEFSTUFDWSBTVEFGRiIsIkFDQ09VTlRTIFNUQUZGIiwiTEFCIFJFQ0VQVElPTklTVCIsIkVSIE5VUlNFIiwiSU5QQVRJRU5UIEJJTExJTkcgU1VQRVJWSVNPUiIsIkxEUi1PUiBOVVJTRVMiLCJBRE1JU1NJT04gU1RBRkYiLCJIRUxQIERFU0sgQURNSU4iLCJBUFBST1ZBTCBTVEFGRiIsIklOUEFUSUVOVCBCSUxMSU5HIENPT1JESU5BVE9SIiwiQklMTElORyBTVEFGRiIsIkNPTlNFTlQgIiwiQ29uc2VudCAtIERlbnRhbCIsIldFQkVNUiJdLCJuYmYiOjE2MDgwMjg0NzQsImV4cCI6MTYwODg5MjQ3NCwiaWF0IjoxNjA4MDI4NDc0fQ.8OJcy6vUuPnNTi_qSjip8YCrFdaRLtJKbNKXcMtnQxk" }, ); } @@ -48,4 +48,5 @@ class DashboardService extends BaseService { }, ); } + } diff --git a/lib/core/service/home/scan_qr_service.dart b/lib/core/service/home/scan_qr_service.dart new file mode 100644 index 00000000..bc6c8820 --- /dev/null +++ b/lib/core/service/home/scan_qr_service.dart @@ -0,0 +1,41 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class ScanQrService extends BaseService { + List myInPatientList = List(); + List inPatientList = List(); + + Future getInPatient(PatientSearchRequestModel requestModel, bool isMyInpatient) async { + hasError = false; + await getDoctorProfile(); + + if (isMyInpatient) { + requestModel.doctorID = doctorProfile.doctorID; + } else { + requestModel.doctorID = 0; + } + + await baseAppClient.post( + GET_PATIENT_IN_PATIENT_LIST, + onSuccess: (dynamic response, int statusCode) { + inPatientList.clear(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } +} diff --git a/lib/core/service/patient/LiveCarePatientServices.dart b/lib/core/service/patient/LiveCarePatientServices.dart index 5b528a33..d8e56db7 100644 --- a/lib/core/service/patient/LiveCarePatientServices.dart +++ b/lib/core/service/patient/LiveCarePatientServices.dart @@ -1,5 +1,8 @@ + import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/model/live_care/AlternativeServicesList.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/live_care/live_care_login_reguest_model.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/livecare/end_call_req.dart'; import 'package:doctor_app_flutter/models/livecare/start_call_req.dart'; @@ -11,8 +14,12 @@ class LiveCarePatientServices extends BaseService { List get patientList => _patientList; + List alternativeServicesList = []; + bool _isFinished = false; + bool _isLive = true; + bool get isFinished => _isFinished; setFinished(bool isFinished) { @@ -21,12 +28,14 @@ class LiveCarePatientServices extends BaseService { var endCallResponse = {}; var transferToAdminResponse = {}; + var isLoginResponse = {}; late StartCallRes _startCallRes; StartCallRes get startCallRes => _startCallRes; Future getPendingPatientERForDoctorApp( - PendingPatientERForDoctorAppRequestModel pendingPatientERForDoctorAppRequestModel) async { + PendingPatientERForDoctorAppRequestModel + pendingPatientERForDoctorAppRequestModel) async { hasError = false; await baseAppClient.post( GET_PENDING_PATIENT_ER_FOR_DOCTOR_APP, @@ -51,7 +60,7 @@ class LiveCarePatientServices extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: endCallReq.toJson(), isLiveCare: true); + }, body: endCallReq.toJson(), isLiveCare: _isLive); } Future startCall(StartCallReq startCallReq) async { @@ -61,10 +70,10 @@ class LiveCarePatientServices extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: startCallReq.toJson(), isLiveCare: true); + }, body: startCallReq.toJson(), isLiveCare: _isLive); } - Future endCallWithCharge(int vcID) async { + Future endCallWithCharge(int vcID, List altServiceList) async { hasError = false; await baseAppClient.post(END_CALL_WITH_CHARGE, onSuccess: (dynamic response, int statusCode) { endCallResponse = response; @@ -73,8 +82,8 @@ class LiveCarePatientServices extends BaseService { super.error = error; }, body: { "VC_ID": vcID, - "generalid": "Cs2020@2016\$2958", - }, isLiveCare: true); + "AltServiceList": altServiceList,"generalid": GENERAL_ID + }, isLiveCare: _isLive); } Future transferToAdmin(int vcID, String notes) async { @@ -88,6 +97,49 @@ class LiveCarePatientServices extends BaseService { "VC_ID": vcID, "IsOutKsa": false, "Notes": notes, - }, isLiveCare: true); + }, isLiveCare: _isLive); + } + + Future sendSMSInstruction(int vcID) async { + hasError = false; + await baseAppClient.post(SEND_SMS_INSTRUCTIONS, + onSuccess: (dynamic response, int statusCode) { + transferToAdminResponse = response; + }, onFailure: (String error, int statusCode) { + hasError =true; + super.error = error; + }, body: { + "VC_ID": vcID, "generalid": GENERAL_ID + }, isLiveCare: _isLive); + } + + Future isLogin({LiveCareUserLoginRequestModel isLoginRequestModel, int loginStatus}) async { + hasError = false; + await getDoctorProfile( ); + isLoginRequestModel.doctorId = super.doctorProfile.doctorID; + await baseAppClient.post(LIVE_CARE_IS_LOGIN, onSuccess: (response, statusCode) async { + isLoginResponse = response; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: isLoginRequestModel.toJson(), isLiveCare: _isLive); + } + + Future getAlternativeServices(int vcID) async { + hasError = false; + alternativeServicesList.clear(); + + await baseAppClient.post(GET_ALTERNATIVE_SERVICE, + onSuccess: (dynamic response, int statusCode) { + response['AlternativeServicesList'].forEach((v) { + alternativeServicesList.add(AlternativeService.fromJson(v)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: { + "VC_ID": vcID, + "generalid": GENERAL_ID + }, isLiveCare: _isLive); } } diff --git a/lib/core/service/patient/MyReferralPatientService.dart b/lib/core/service/patient/MyReferralPatientService.dart index d1ef47fa..c2e467d2 100644 --- a/lib/core/service/patient/MyReferralPatientService.dart +++ b/lib/core/service/patient/MyReferralPatientService.dart @@ -1,5 +1,7 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/request_add_referred_doctor_remarks.dart'; @@ -8,22 +10,21 @@ class MyReferralInPatientService extends BaseService { Future getMyReferralPatientService() async { hasError = false; - Map body = Map(); await getDoctorProfile(); - body['DoctorID'] = doctorProfile!.doctorID; - body['FirstName'] = "0"; - body['MiddleName'] = "0"; - body['LastName'] = "0"; - body['PatientMobileNumber'] = "0"; - body['PatientIdentificationID'] = "0"; - body['PatientID'] = 0; - body['From'] = "0"; - body['To'] = "0"; - body['stamp'] = DateTime.now().toIso8601String(); - body['IsLoginForDoctorApp'] = true; - body['IPAdress'] = "11.11.11.11"; - body['PatientOutSA'] = false; - body['PatientTypeID'] = 1; + + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( + doctorID: doctorProfile!.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); myReferralPatients.clear(); await baseAppClient.post( GET_MY_REFERRAL_INPATIENT, @@ -38,7 +39,42 @@ class MyReferralInPatientService extends BaseService { hasError = true; super.error = error; }, - body: body, + body: myReferralPatientRequestModel.toJson(), + ); + } + + Future getMyReferralOutPatientService() async { + hasError = false; + await getDoctorProfile(); + + MyReferralPatientRequestModel myReferralPatientRequestModel = MyReferralPatientRequestModel( + doctorID: doctorProfile.doctorID, + firstName: "0", + middleName: "0", + lastName: "0", + patientMobileNumber: "0", + patientIdentificationID: "0", + patientID: 0, + from: "0", + to: "0", + stamp: DateTime.now().toIso8601String(), + isLoginForDoctorApp: true, + patientTypeID: 1); + myReferralPatients.clear(); + await baseAppClient.post( + GET_MY_REFERRAL_OUT_PATIENT, + onSuccess: (dynamic response, int statusCode) { + if (response['List_MyOutPatientReferral'] != null) { + response['List_MyOutPatientReferral'].forEach((v) { + myReferralPatients.add(MyReferralPatientModel.fromJson(v)); + }); + } + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: myReferralPatientRequestModel.toJson(), ); } @@ -63,4 +99,32 @@ class MyReferralInPatientService extends BaseService { }, ); } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + hasError = false; + await getDoctorProfile(); + AddReferredRemarksRequestModel _requestAddReferredDoctorRemarks = AddReferredRemarksRequestModel( + editedBy: doctorProfile.doctorID, + projectID: doctorProfile.projectID, + referredDoctorRemarks: referredDoctorRemarks, + referalStatus: referalStatus); + _requestAddReferredDoctorRemarks.projectID = referral.projectID; + _requestAddReferredDoctorRemarks.admissionNo = int.parse(referral.admissionNo); + _requestAddReferredDoctorRemarks.lineItemNo = referral.lineItemNo; + _requestAddReferredDoctorRemarks.referredDoctorRemarks = referredDoctorRemarks; + _requestAddReferredDoctorRemarks.editedBy = doctorProfile.doctorID; + _requestAddReferredDoctorRemarks.referalStatus = referalStatus; + + // _requestAddReferredDoctorRemarks.patientID = referral.patientID; + // _requestAddReferredDoctorRemarks.referringDoctor = referral.referringDoctor; + await baseAppClient.post( + ADD_REFERRED_REMARKS_NEW, + body: _requestAddReferredDoctorRemarks.toJson(), + onSuccess: (dynamic body, int statusCode) {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } } diff --git a/lib/core/service/patient/patient-doctor-referral-service.dart b/lib/core/service/patient/patient-doctor-referral-service.dart index abf3fab3..08e17574 100644 --- a/lib/core/service/patient/patient-doctor-referral-service.dart +++ b/lib/core/service/patient/patient-doctor-referral-service.dart @@ -151,6 +151,36 @@ class PatientReferralService extends LookupService { ); } + Future getMyReferredOutPatient() async { + hasError = false; + RequestMyReferralPatientModel _requestMyReferralPatient = + RequestMyReferralPatientModel(); + DoctorProfileModel doctorProfile = await getDoctorProfile(); + + await baseAppClient.post( + GET_MY_REFERRED_OUT_PATIENT, + onSuccess: (dynamic response, int statusCode) { + listMyReferredPatientModel.clear(); + + response['List_MyReferredOutPatient'].forEach((v) { + MyReferredPatientModel item = MyReferredPatientModel.fromJson(v); + if (doctorProfile != null) { + item.isReferralDoctorSameBranch = + doctorProfile.projectID == item.projectID; + } else { + item.isReferralDoctorSameBranch = false; + } + listMyReferredPatientModel.add(item); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: _requestMyReferralPatient.toJson(), + ); + } + Future getPendingReferralList() async { hasError = false; DoctorProfileModel? doctorProfile = await getDoctorProfile(); diff --git a/lib/core/service/patient/patient_service.dart b/lib/core/service/patient/patient_service.dart index 8eedb7de..31632d27 100644 --- a/lib/core/service/patient/patient_service.dart +++ b/lib/core/service/patient/patient_service.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/get_clinic_by_project_id_request.dart'; @@ -12,6 +13,7 @@ import 'package:doctor_app_flutter/models/patient/get_list_stp_referral_frequenc import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result_req_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -22,6 +24,8 @@ import 'package:doctor_app_flutter/models/patient/vital_sign/vital_sign_res_mode class PatientService extends BaseService { List _patientVitalSignList = []; List patientVitalSignOrderdSubList = []; + List inPatientList = List(); + List myInPatientList = List(); List get patientVitalSignList => _patientVitalSignList; @@ -132,6 +136,38 @@ class PatientService extends BaseService { return Future.value(localRes); } + Future getInPatient(PatientSearchRequestModel requestModel, bool isMyInpatient) async { + hasError = false; + await getDoctorProfile(); + + if (isMyInpatient) { + requestModel.doctorID = doctorProfile.doctorID; + } else { + requestModel.doctorID = 0; + } + + await baseAppClient.post( + GET_PATIENT_IN_PATIENT_LIST, + onSuccess: (dynamic response, int statusCode) { + inPatientList.clear(); + myInPatientList.clear(); + + response['List_MyInPatient'].forEach((v) { + PatiantInformtion patient = PatiantInformtion.fromJson(v); + inPatientList.add(patient); + if (patient.doctorId == doctorProfile.doctorID) { + myInPatientList.add(patient); + } + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: requestModel.toJson(), + ); + } + Future getLabResultOrders(patient) async { hasError = false; await baseAppClient.post( diff --git a/lib/core/service/patient/referred_patient_service.dart b/lib/core/service/patient/referred_patient_service.dart deleted file mode 100644 index 0af9b077..00000000 --- a/lib/core/service/patient/referred_patient_service.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/core/service/base/base_service.dart'; -import 'package:doctor_app_flutter/models/doctor/verify_referral_doctor_remarks.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/my_referred_patient_model.dart'; -import 'package:doctor_app_flutter/models/patient/request_my_referral_patient_model.dart'; - -class ReferredPatientService extends BaseService { - List _listMyReferredPatientModel = []; - - List get listMyReferredPatientModel => - _listMyReferredPatientModel; - - RequestMyReferralPatientModel _requestMyReferralPatient = - RequestMyReferralPatientModel(); - VerifyReferralDoctorRemarks _verifyreferraldoctorremarks = - VerifyReferralDoctorRemarks(); - - Future getMyReferredPatient() async { - await baseAppClient.post( - GET_MY_REFERRED_PATIENT, - onSuccess: (dynamic response, int statusCode) { - _listMyReferredPatientModel.clear(); - response['List_MyReferredPatient'].forEach((v) { - listMyReferredPatientModel.add(MyReferredPatientModel.fromJson(v)); - }); - // print(response['List_MyReferredPatient']); - }, - onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, - body: _requestMyReferralPatient.toJson(), - ); - } - -} diff --git a/lib/core/service/patient_medical_file/procedure/procedure_service.dart b/lib/core/service/patient_medical_file/procedure/procedure_service.dart index 6a757986..48a93853 100644 --- a/lib/core/service/patient_medical_file/procedure/procedure_service.dart +++ b/lib/core/service/patient_medical_file/procedure/procedure_service.dart @@ -61,7 +61,7 @@ class ProcedureService extends BaseService { Future getProcedureTemplate({int? doctorId, int? projectId, int? clinicId, String? categoryID}) async { _procedureTempleteRequestModel = ProcedureTempleteRequestModel( - tokenID: "@dm!n", + // tokenID: "@dm!n", patientID: 0, searchType: 1, ); diff --git a/lib/core/service/patient_medical_file/radiology/radiology_service.dart b/lib/core/service/patient_medical_file/radiology/radiology_service.dart index 771ee179..63dcd188 100644 --- a/lib/core/service/patient_medical_file/radiology/radiology_service.dart +++ b/lib/core/service/patient_medical_file/radiology/radiology_service.dart @@ -40,6 +40,9 @@ class RadiologyService extends BaseService { if (isInPatient) { label = "List_GetRadOreders"; } + if(response[label] == null || response[label].length == 0){ + label = "FinalRadiologyList"; + } response[label].forEach((radiology) { finalRadiologyList.add(FinalRadiology.fromJson(radiology)); }); diff --git a/lib/core/service/special_clinics/special_clinic_service.dart b/lib/core/service/special_clinics/special_clinic_service.dart new file mode 100644 index 00000000..49237331 --- /dev/null +++ b/lib/core/service/special_clinics/special_clinic_service.dart @@ -0,0 +1,57 @@ +import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/core/service/base/base_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; + +class SpecialClinicsService extends BaseService { + + + List _specialClinicalCareList = []; + List get specialClinicalCareList => _specialClinicalCareList; + + List _specialClinicalCareMappingList = []; + List get specialClinicalCareMappingList => _specialClinicalCareMappingList; + Future getSpecialClinicalCareList() async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareList.clear(); + response['List_SpecialClinicalCareList'].forEach((v) { + _specialClinicalCareList.add(GetSpecialClinicalCareListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + }, + ); + } + + + Future getSpecialClinicalCareMappingList(int clinicId) async { + hasError = false; + await baseAppClient.post( + GET_SPECIAL_CLINICAL_CARE_MAPPING_LIST, + onSuccess: (dynamic response, int statusCode) { + + _specialClinicalCareMappingList.clear(); + response['List_SpecialClinicalCareMappingList'].forEach((v) { + _specialClinicalCareMappingList.add(GetSpecialClinicalCareMappingListResponseModel.fromJson(v)); + });}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + body: { + "ClinicID": clinicId, + "DoctorID":0, + "EditedBy":0 + }, + ); + } + +} diff --git a/lib/core/viewModel/LiveCarePatientViewModel.dart b/lib/core/viewModel/LiveCarePatientViewModel.dart index c963e0f9..907bc1da 100644 --- a/lib/core/viewModel/LiveCarePatientViewModel.dart +++ b/lib/core/viewModel/LiveCarePatientViewModel.dart @@ -1,6 +1,8 @@ import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/live_care/AlternativeServicesList.dart'; import 'package:doctor_app_flutter/core/model/live_care/PendingPatientERForDoctorAppRequestModel.dart'; +import 'package:doctor_app_flutter/core/model/live_care/live_care_login_reguest_model.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/patient/LiveCarePatientServices.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; @@ -18,6 +20,9 @@ class LiveCarePatientViewModel extends BaseViewModel { StartCallRes get startCallRes => _liveCarePatientServices.startCallRes; + List get alternativeServicesList => + _liveCarePatientServices.alternativeServicesList; + DashboardService _dashboardService = locator(); getPendingPatientERForDoctorApp({bool isFromTimer = false}) async { @@ -87,9 +92,22 @@ class LiveCarePatientViewModel extends BaseViewModel { } } - Future endCallWithCharge(int vcID) async { + setSelectedCheckboxValues(AlternativeService service, bool isSelected) { + int index = alternativeServicesList.indexOf(service); + if (index != -1) alternativeServicesList[index].isSelected = isSelected; + notifyListeners(); + } + + Future endCallWithCharge(int vcID, bool isConfirmed) async { setState(ViewState.BusyLocal); - await _liveCarePatientServices.endCallWithCharge(vcID); + + List selectedServices = []; + if (isConfirmed) { + selectedServices = getSelectedAlternativeServices(); + } + + await _liveCarePatientServices.endCallWithCharge( + vcID, selectedServices); if (_liveCarePatientServices.hasError) { error = _liveCarePatientServices.error!; setState(ViewState.ErrorLocal); @@ -99,6 +117,27 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + List getSelectedAlternativeServices() { + List selectedServices = List(); + for (AlternativeService service in alternativeServicesList) { + if (service.isSelected) { + selectedServices.add(service.serviceID); + } + } + return selectedServices; + } + + Future getAlternativeServices(int vcID) async { + setState(ViewState.BusyLocal); + await _liveCarePatientServices.getAlternativeServices(vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + Future transferToAdmin(int vcID, String notes) async { setState(ViewState.BusyLocal); await _liveCarePatientServices.transferToAdmin(vcID, notes); @@ -111,6 +150,18 @@ class LiveCarePatientViewModel extends BaseViewModel { } } + Future sendSMSInstruction(int vcID) async { + setState(ViewState.BusyLocal); + await _liveCarePatientServices.sendSMSInstruction(vcID); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + await getPendingPatientERForDoctorApp(); + setState(ViewState.Idle); + } + } + searchData(String str) { var strExist = str.length > 0 ? true : false; if (strExist) { @@ -130,4 +181,61 @@ class LiveCarePatientViewModel extends BaseViewModel { notifyListeners(); } } + + Future isLogin(int loginStatus) async { + await getDoctorProfile(isGetProfile: true); + + LiveCareUserLoginRequestModel userLoginRequestModel = new LiveCareUserLoginRequestModel(); + userLoginRequestModel.isOutKsa = (doctorProfile.projectID == 2 || doctorProfile.projectID == 3) ? 1 : 0; + userLoginRequestModel.isLogin = loginStatus; + userLoginRequestModel.generalid = "Cs2020@2016\$2958"; + + setState(ViewState.BusyLocal); + await _liveCarePatientServices.isLogin(loginStatus: loginStatus, isLoginRequestModel: userLoginRequestModel); + if (_liveCarePatientServices.hasError) { + error = _liveCarePatientServices.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + setDemoData() { + alternativeServicesList.clear(); + alternativeServicesList.add( + AlternativeService(serviceID: 1, serviceName: "Medicine Home Delivery"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 2, serviceName: "LABORATORY"), + ); + alternativeServicesList.add( + AlternativeService( + serviceID: 3, serviceName: "RADIOLOGY(ULTRASOUND) For pregnant only"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 4, serviceName: "VACCINATIONS"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 5, serviceName: "ER SERVICES"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 6, serviceName: "PHYSIOTHERAPY"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 7, serviceName: "DRESSING"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 8, serviceName: "INJECTION"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 9, serviceName: "FAMILY MEDICIN DR"), + ); + alternativeServicesList.add( + AlternativeService( + serviceID: 10, serviceName: "FOLYS CATHETER INSERTION"), + ); + alternativeServicesList.add( + AlternativeService(serviceID: 11, serviceName: "GASTRIC TUBE CHANGE"), + ); + } } diff --git a/lib/core/viewModel/PatientMedicalReportViewModel.dart b/lib/core/viewModel/PatientMedicalReportViewModel.dart index 4a9045be..8dbbc64d 100644 --- a/lib/core/viewModel/PatientMedicalReportViewModel.dart +++ b/lib/core/viewModel/PatientMedicalReportViewModel.dart @@ -25,12 +25,24 @@ class PatientMedicalReportViewModel extends BaseViewModel { setState(ViewState.Idle); } + bool hasOnHold(){ + bool hasHold = false; + medicalReportList.forEach((element) { + if(element.status == 1){ + hasHold = true; + } + }); + + return hasHold; + + } + Future getMedicalReportTemplate() async { - setState(ViewState.Busy); + setState(ViewState.BusyLocal); await _service.getMedicalReportTemplate(); if (_service.hasError) { error = _service.error!; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); } diff --git a/lib/core/viewModel/PatientSearchViewModel.dart b/lib/core/viewModel/PatientSearchViewModel.dart index 9cc1110b..d0bd9862 100644 --- a/lib/core/viewModel/PatientSearchViewModel.dart +++ b/lib/core/viewModel/PatientSearchViewModel.dart @@ -4,6 +4,8 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/patient/out_patient_service.dart'; import 'package:doctor_app_flutter/core/service/patient/patientInPatientService.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; @@ -12,8 +14,10 @@ import 'base_view_model.dart'; class PatientSearchViewModel extends BaseViewModel { OutPatientService _outPatientService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get patientList => _outPatientService.patientList; + List get specialClinicalCareMappingList => _specialClinicsService.specialClinicalCareMappingList; List filterData = []; @@ -123,14 +127,21 @@ class PatientSearchViewModel extends BaseViewModel { List filteredInPatientItems = []; - Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false, bool isLocalBusy = false}) async { await getDoctorProfile(); - setState(ViewState.Busy); - + if(isLocalBusy) { + setState(ViewState.BusyLocal); + } else{ + setState(ViewState.Busy); + } if (inPatientList.length == 0) await _inPatientService.getInPatientList(requestModel, false); if (_inPatientService.hasError) { error = _inPatientService.error!; + if(isLocalBusy) { + setState(ViewState.ErrorLocal); + } else{ setState(ViewState.Error); + } } else { // setDefaultInPatientList(); setState(ViewState.Idle); @@ -145,6 +156,9 @@ class PatientSearchViewModel extends BaseViewModel { setState(ViewState.Idle); } + + + void clearPatientList() { _inPatientService.inPatientList = []; _inPatientService.myInPatientList = []; @@ -174,4 +188,25 @@ class PatientSearchViewModel extends BaseViewModel { notifyListeners(); } } + + + getSpecialClinicalCareMappingList(clinicId, + {bool isLocalBusy = false}) async { + if (isLocalBusy) { + setState(ViewState.BusyLocal); + } else { + setState(ViewState.Busy); + } + await _specialClinicsService.getSpecialClinicalCareMappingList(clinicId); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; + if (isLocalBusy) { + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Error); + } + } else { + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModel/authentication_view_model.dart b/lib/core/viewModel/authentication_view_model.dart index a6692563..f63220d4 100644 --- a/lib/core/viewModel/authentication_view_model.dart +++ b/lib/core/viewModel/authentication_view_model.dart @@ -26,9 +26,7 @@ import 'package:doctor_app_flutter/root_page.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; @@ -234,7 +232,8 @@ class AuthenticationViewModel extends BaseViewModel { /// add  token to shared preferences in case of send activation code is success setDataAfterSendActivationSuccess( SendActivationCodeForDoctorAppResponseModel sendActivationCodeForDoctorAppResponseModel) { - print("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode!); + print("VerificationCode : " +sendActivationCodeForDoctorAppResponseModel.verificationCode); + // DrAppToastMsg.showSuccesToast("VerificationCode : " + sendActivationCodeForDoctorAppResponseModel.verificationCode!); sharedPref.setString(VIDA_AUTH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaAuthTokenID!); sharedPref.setString(VIDA_REFRESH_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.vidaRefreshTokenID!); sharedPref.setString(LOGIN_TOKEN_ID, sendActivationCodeForDoctorAppResponseModel.logInTokenID!); @@ -275,8 +274,7 @@ class AuthenticationViewModel extends BaseViewModel { clinicID: clinicInfo.clinicID, license: true, projectID: clinicInfo.projectID, - tokenID: '', - languageID: 2); //TODO change the lan + tokenID: '',); //TODO change the lan await _authService.getDoctorProfileBasedOnClinic(docInfo); if (_authService.hasError) { error = _authService.error!; diff --git a/lib/core/viewModel/dashboard_view_model.dart b/lib/core/viewModel/dashboard_view_model.dart index 8fe5a88c..e85c103c 100644 --- a/lib/core/viewModel/dashboard_view_model.dart +++ b/lib/core/viewModel/dashboard_view_model.dart @@ -2,8 +2,10 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/service/home/dasboard_service.dart'; +import 'package:doctor_app_flutter/core/service/special_clinics/special_clinic_service.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -14,6 +16,7 @@ import 'base_view_model.dart'; class DashboardViewModel extends BaseViewModel { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; DashboardService _dashboardService = locator(); + SpecialClinicsService _specialClinicsService = locator(); List get dashboardItemsList => _dashboardService.dashboardItemsList; @@ -21,6 +24,9 @@ class DashboardViewModel extends BaseViewModel { String? get sServiceID => _dashboardService.sServiceID; + List get specialClinicalCareList => _specialClinicsService.specialClinicalCareList; + + Future setFirebaseNotification(ProjectViewModel projectsProvider, AuthenticationViewModel authProvider) async { setState(ViewState.Busy); await projectsProvider.getDoctorClinicsList(); @@ -56,6 +62,16 @@ class DashboardViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getSpecialClinicalCareList() async { + setState(ViewState.Busy); + await _specialClinicsService.getSpecialClinicalCareList(); + if (_specialClinicsService.hasError) { + error = _specialClinicsService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + Future changeClinic(int clinicId, AuthenticationViewModel authProvider) async { setState(ViewState.BusyLocal); await getDoctorProfile(); @@ -76,4 +92,17 @@ class DashboardViewModel extends BaseViewModel { return value.toString(); } + + + GetSpecialClinicalCareListResponseModel getSpecialClinic(clinicId){ + GetSpecialClinicalCareListResponseModel special ; + specialClinicalCareList.forEach((element) { + if(element.clinicID == 1){ + special = element; + } + }); + + return special; + + } } diff --git a/lib/core/viewModel/patient-referral-viewmodel.dart b/lib/core/viewModel/patient-referral-viewmodel.dart index c1ae248a..520004a4 100644 --- a/lib/core/viewModel/patient-referral-viewmodel.dart +++ b/lib/core/viewModel/patient-referral-viewmodel.dart @@ -2,6 +2,7 @@ import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/referral/DischargeReferralPatient.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/service/patient/DischargedPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/MyReferralPatientService.dart'; import 'package:doctor_app_flutter/core/service/patient/ReferralService.dart'; @@ -119,8 +120,11 @@ class PatientReferralViewModel extends BaseViewModel { return null; } - Future getMyReferredPatient() async { - setState(ViewState.Busy); + Future getMyReferredPatient({bool isFirstTime = true}) async { + if (isFirstTime) + setState(ViewState.Busy); + else + setState(ViewState.BusyLocal); await _referralPatientService.getMyReferredPatient(); if (_referralPatientService.hasError) { error = _referralPatientService.error!; @@ -129,6 +133,19 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } + Future getMyReferredOutPatient({bool isFirstTime = true}) async { + if (isFirstTime) + setState(ViewState.Busy); + else + setState(ViewState.BusyLocal); + await _referralPatientService.getMyReferredOutPatient(); + if (_referralPatientService.hasError) { + error = _referralPatientService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + MyReferredPatientModel getReferredPatientItem(int index) { return listMyReferredPatientModel[index]; } @@ -143,12 +160,34 @@ class PatientReferralViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getMyReferralPatientService() async { - setState(ViewState.Busy); + Future getMyReferralPatientService({bool localBusy = false}) async { + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); await _myReferralService.getMyReferralPatientService(); if (_myReferralService.hasError) { error = _myReferralService.error!; - setState(ViewState.Error); + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future getMyReferralOutPatientService({bool localBusy = false}) async { + if (localBusy) + setState(ViewState.BusyLocal); + else + setState(ViewState.Busy); + await _myReferralService.getMyReferralOutPatientService(); + if (_myReferralService.hasError) { + error = _myReferralService.error; + if (localBusy) + setState(ViewState.ErrorLocal); + else + setState(ViewState.Error); } else setState(ViewState.Idle); } @@ -200,7 +239,7 @@ class PatientReferralViewModel extends BaseViewModel { patientID: patient.patientId, roomID: patient.roomId, referralClinic: clinicID, - admissionNo: int.parse(patient.admissionNo!), /// TODO Elham* something in case inpateint since we send send appointmentNo for admissionNo which all time null + admissionNo: int.parse(patient.admissionNo), referralDoctor: doctorID, patientTypeID: patient.patientType, referringDoctorRemarks: remarks, @@ -351,4 +390,14 @@ class PatientReferralViewModel extends BaseViewModel { patient.clinicDescription = referredPatient.clinicDescription!; return patient; } + + Future replayReferred(String referredDoctorRemarks, MyReferralPatientModel referral, int referalStatus) async { + setState(ViewState.Busy); + await _myReferralService.replayReferred(referredDoctorRemarks, referral, referalStatus); + if (_myReferralService.hasError) { + error = _myReferralService.error; + setState(ViewState.ErrorLocal); + } else + getMyReferralPatientService(); + } } diff --git a/lib/core/viewModel/patient_view_model.dart b/lib/core/viewModel/patient_view_model.dart index 547dbdec..af0130d8 100644 --- a/lib/core/viewModel/patient_view_model.dart +++ b/lib/core/viewModel/patient_view_model.dart @@ -2,9 +2,11 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart'; import 'package:doctor_app_flutter/core/model/note/note_model.dart'; import 'package:doctor_app_flutter/core/model/note/update_note_model.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/service/patient/patient_service.dart'; import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart'; import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart'; import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart'; @@ -17,51 +19,43 @@ import 'base_view_model.dart'; class PatientViewModel extends BaseViewModel { PatientService _patientService = locator(); - List get patientVitalSignList => - _patientService.patientVitalSignList; + List get inPatientList => _patientService.inPatientList; - List get patientVitalSignOrderdSubList => - _patientService.patientVitalSignOrderdSubList; + List get patientVitalSignList => _patientService.patientVitalSignList; - List get patientLabResultOrdersList => - _patientService.patientLabResultOrdersList; + List get patientVitalSignOrderdSubList => _patientService.patientVitalSignOrderdSubList; - List get patientPrescriptionsList => - _patientService.patientPrescriptionsList; + List get patientLabResultOrdersList => _patientService.patientLabResultOrdersList; + + List get patientPrescriptionsList => _patientService.patientPrescriptionsList; List get prescriptionReportForInPatientList => _patientService.prescriptionReportForInPatientList; - List get prescriptionReport => - _patientService.prescriptionReport; + List get prescriptionReport => _patientService.prescriptionReport; - List get patientRadiologyList => - _patientService.patientRadiologyList; + List get patientRadiologyList => _patientService.patientRadiologyList; List get labResultList => _patientService.labResultList; get insuranceApporvalsList => _patientService.insuranceApporvalsList; - List get patientProgressNoteList => - _patientService.patientProgressNoteList; + List get patientProgressNoteList => _patientService.patientProgressNoteList; List get clinicsList => _patientService.clinicsList; List get doctorsList => _patientService.doctorsList; - List get referralFrequencyList => - _patientService.referalFrequancyList; + List get referralFrequencyList => _patientService.referalFrequancyList; - Future getPatientList(patient, patientType, - {bool isBusyLocal = false, isView}) async { + Future getPatientList(patient, patientType, {bool isBusyLocal = false, isView}) async { var localRes; if (isBusyLocal) { setState(ViewState.BusyLocal); } else { setState(ViewState.Busy); } - localRes = await _patientService.getPatientList(patient, patientType, - isView: isView); + localRes = await _patientService.getPatientList(patient, patientType, isView: isView); if (_patientService.hasError) { error = _patientService.error!; @@ -210,16 +204,12 @@ class PatientViewModel extends BaseViewModel { } List getDoctorNameList() { - var doctorNamelist = _patientService.doctorsList - .map((value) => value['DoctorName'].toString()) - .toList(); + var doctorNamelist = _patientService.doctorsList.map((value) => value['DoctorName'].toString()).toList(); return doctorNamelist; } List getClinicNameList() { - var clinicsNameslist = _patientService.clinicsList - .map((value) => value['ClinicDescription'].toString()) - .toList(); + var clinicsNameslist = _patientService.clinicsList.map((value) => value['ClinicDescription'].toString()).toList(); return clinicsNameslist; } @@ -234,9 +224,8 @@ class PatientViewModel extends BaseViewModel { } List getReferralNamesList() { - var referralNamesList = _patientService.referalFrequancyList - .map((value) => value['Description'].toString()) - .toList(); + var referralNamesList = + _patientService.referalFrequancyList.map((value) => value['Description'].toString()).toList(); return referralNamesList; } @@ -281,4 +270,18 @@ class PatientViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _patientService.getInPatient(requestModel, false); + if (_patientService.hasError) { + error = _patientService.error; + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModel/procedure_View_model.dart b/lib/core/viewModel/procedure_View_model.dart index 43758e65..6fc0f7e1 100644 --- a/lib/core/viewModel/procedure_View_model.dart +++ b/lib/core/viewModel/procedure_View_model.dart @@ -4,10 +4,10 @@ import 'package:doctor_app_flutter/core/model/labs/LabOrderResult.dart'; import 'package:doctor_app_flutter/core/model/labs/lab_result.dart'; import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/model/labs/patient_lab_special_result.dart'; +import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; @@ -19,8 +19,12 @@ import 'package:doctor_app_flutter/core/service/patient_medical_file/radiology/r import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:flutter/cupertino.dart'; +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart' + as cpe; class ProcedureViewModel extends BaseViewModel { //TODO Hussam clean it @@ -74,11 +78,15 @@ class ProcedureViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getProcedureCategory({String? categoryName, String? categoryID, patientId}) async { + Future getProcedureCategory( + {String? categoryName, String? categoryID, patientId}) async { + if (categoryName == null) return; hasError = false; setState(ViewState.Busy); await _procedureService.getProcedureCategory( - categoryName: categoryName, categoryID: categoryID, patientId: patientId); + categoryName: categoryName, + categoryID: categoryID, + patientId: patientId); if (_procedureService.hasError) { error = _procedureService.error!; setState(ViewState.ErrorLocal); @@ -305,4 +313,70 @@ class ProcedureViewModel extends BaseViewModel { } else DrAppToastMsg.showSuccesToast(mes); } + + Future preparePostProcedure( + {String remarks, + String orderType, + PatiantInformtion patient, + List entityList, + ProcedureType procedureType}) async { + PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); + ProcedureValadteRequestModel procedureValadteRequestModel = + new ProcedureValadteRequestModel(); + procedureValadteRequestModel.patientMRN = patient.patientMRN; + procedureValadteRequestModel.episodeID = patient.episodeNo; + procedureValadteRequestModel.appointmentNo = patient.appointmentNo; + + List controlsProcedure = List(); + + postProcedureReqModel.appointmentNo = patient.appointmentNo; + postProcedureReqModel.episodeID = patient.episodeNo; + postProcedureReqModel.patientMRN = patient.patientMRN; + + entityList.forEach((element) { + procedureValadteRequestModel.procedure = [element.procedureId]; + List controls = List(); + controls.add( + Controls( + code: "remarks", + controlValue: element.remarks != null ? element.remarks : ""), + ); + controls.add( + Controls( + code: "ordertype", + controlValue: procedureType == ProcedureType.PROCEDURE + ? element.type ?? "1" + : "0"), + ); + controlsProcedure.add(Procedures( + category: element.categoryID, + procedure: element.procedureId, + controls: controls)); + }); + + postProcedureReqModel.procedures = controlsProcedure; + await valadteProcedure(procedureValadteRequestModel); + if (state == ViewState.Idle) { + if (valadteProcedureList[0].entityList.length == 0) { + await postProcedure(postProcedureReqModel, patient.patientMRN); + + if (state == ViewState.ErrorLocal) { + Helpers.showErrorToast(error); + getProcedure(mrn: patient.patientMRN); + } else if (state == ViewState.Idle) { + DrAppToastMsg.showSuccesToast('procedure has been added'); + } + } else { + if (state == ViewState.ErrorLocal) { + Helpers.showErrorToast(error); + getProcedure(mrn: patient.patientMRN); + } else if (state == ViewState.Idle) { + Helpers.showErrorToast( + valadteProcedureList[0].entityList[0].warringMessages); + } + } + } else { + Helpers.showErrorToast(error); + } + } } diff --git a/lib/core/viewModel/referred_view_model.dart b/lib/core/viewModel/referred_view_model.dart deleted file mode 100644 index da99d26b..00000000 --- a/lib/core/viewModel/referred_view_model.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/service/patient/referred_patient_service.dart'; -import 'package:doctor_app_flutter/models/patient/my_referral/my_referred_patient_model.dart'; - -import '../../locator.dart'; -import 'base_view_model.dart'; - -class ReferredPatientViewModel extends BaseViewModel { - ReferredPatientService _referralPatientService = locator(); - - List get listMyReferredPatientModel => _referralPatientService.listMyReferredPatientModel; - - Future getMyReferredPatient() async { - setState(ViewState.Busy); - await _referralPatientService.getMyReferredPatient(); - if (_referralPatientService.hasError) { - error = _referralPatientService.error!; - setState(ViewState.Error); - } else - setState(ViewState.Idle); - } -} diff --git a/lib/core/viewModel/scan_qr_view_model.dart b/lib/core/viewModel/scan_qr_view_model.dart new file mode 100644 index 00000000..86e975e3 --- /dev/null +++ b/lib/core/viewModel/scan_qr_view_model.dart @@ -0,0 +1,26 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; +import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart'; +import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; +import 'package:doctor_app_flutter/locator.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; + +class ScanQrViewModel extends BaseViewModel { + ScanQrService _scanQrService = locator(); + List get inPatientList => _scanQrService.inPatientList; + + Future getInPatientList(PatientSearchRequestModel requestModel, {bool isMyInpatient = false}) async { + await getDoctorProfile(); + setState(ViewState.Busy); + + await _scanQrService.getInPatient(requestModel, true); + if (_scanQrService.hasError) { + error = _scanQrService.error; + + setState(ViewState.ErrorLocal); + } else { + // setDefaultInPatientList(); + setState(ViewState.Idle); + } + } +} diff --git a/lib/landing_page.dart b/lib/landing_page.dart index 90b8453f..0959cd52 100644 --- a/lib/landing_page.dart +++ b/lib/landing_page.dart @@ -4,6 +4,7 @@ import 'package:doctor_app_flutter/screens/home/home_screen.dart'; import 'package:doctor_app_flutter/screens/qr_reader/QR_reader_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_drawer_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/bottom_nav_bar.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -32,7 +33,7 @@ class _LandingPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return AppScaffold( appBar: currentTab != 0 ? AppBar( elevation: 0, diff --git a/lib/locator.dart b/lib/locator.dart index 66ec9161..d74fad8b 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,42 +1,46 @@ import 'package:doctor_app_flutter/core/service/authentication_service.dart'; +import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:get_it/get_it.dart'; +import 'core/service/NavigationService.dart'; +import 'core/service/VideoCallService.dart'; import 'core/service/home/dasboard_service.dart'; +import 'core/service/home/doctor_reply_service.dart'; +import 'core/service/home/schedule_service.dart'; +import 'core/service/hospitals/hospitals_service.dart'; import 'core/service/patient/DischargedPatientService.dart'; import 'core/service/patient/LiveCarePatientServices.dart'; -import 'core/service/patient/patient_service.dart'; -import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; import 'core/service/patient/MyReferralPatientService.dart'; import 'core/service/patient/PatientMuseService.dart'; import 'core/service/patient/ReferralService.dart'; +import 'core/service/patient/out_patient_service.dart'; +import 'core/service/patient/patient-doctor-referral-service.dart'; +import 'core/service/patient/patientInPatientService.dart'; +import 'core/service/patient/patient_service.dart'; +import 'core/service/patient/referral_patient_service.dart'; +import 'core/service/patient_medical_file/admission_request/patient-admission-request-service.dart'; +import 'core/service/patient_medical_file/insurance/InsuranceCardService.dart'; +import 'core/service/patient_medical_file/lab_order/labs_service.dart'; import 'core/service/patient_medical_file/medical_report/PatientMedicalReportService.dart'; import 'core/service/patient_medical_file/medical_report/medical_file_service.dart'; +import 'core/service/patient_medical_file/prescription/medicine_service.dart'; import 'core/service/patient_medical_file/prescription/prescription_service.dart'; +import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; import 'core/service/patient_medical_file/procedure/procedure_service.dart'; +import 'core/service/patient_medical_file/radiology/radiology_service.dart'; import 'core/service/patient_medical_file/sick_leave/sickleave_service.dart'; import 'core/service/patient_medical_file/soap/SOAP_service.dart'; -import 'core/service/home/doctor_reply_service.dart'; -import 'core/service/hospitals/hospitals_service.dart'; -import 'core/service/patient_medical_file/lab_order/labs_service.dart'; -import 'core/service/patient_medical_file/prescription/medicine_service.dart'; -import 'core/service/patient_medical_file/admission_request/patient-admission-request-service.dart'; -import 'core/service/patient/patient-doctor-referral-service.dart'; import 'core/service/patient_medical_file/ucaf/patient-ucaf-service.dart'; import 'core/service/patient_medical_file/vital_sign/patient-vital-signs-service.dart'; -import 'core/service/patient/out_patient_service.dart'; -import 'core/service/patient/patientInPatientService.dart'; -import 'core/service/patient_medical_file/prescription/prescriptions_service.dart'; -import 'core/service/patient_medical_file/radiology/radiology_service.dart'; -import 'core/service/patient/referral_patient_service.dart'; -import 'core/service/patient/referred_patient_service.dart'; -import 'core/service/home/schedule_service.dart'; +import 'core/service/special_clinics/special_clinic_service.dart'; import 'core/viewModel/DischargedPatientViewModel.dart'; import 'core/viewModel/InsuranceViewModel.dart'; import 'core/viewModel/LiveCarePatientViewModel.dart'; @@ -54,7 +58,6 @@ import 'core/viewModel/patient-vital-sign-viewmodel.dart'; import 'core/viewModel/prescriptions_view_model.dart'; import 'core/viewModel/radiology_view_model.dart'; import 'core/viewModel/referral_view_model.dart'; -import 'core/viewModel/referred_view_model.dart'; import 'core/viewModel/schedule_view_model.dart'; GetIt locator = GetIt.instance; @@ -65,7 +68,6 @@ void setupLocator() { locator.registerLazySingleton(() => DoctorReplyService()); locator.registerLazySingleton(() => ScheduleService()); locator.registerLazySingleton(() => ReferralPatientService()); - locator.registerLazySingleton(() => ReferredPatientService()); locator.registerLazySingleton(() => MedicineService()); locator.registerLazySingleton(() => PatientService()); locator.registerLazySingleton(() => DashboardService()); @@ -92,12 +94,15 @@ void setupLocator() { locator.registerLazySingleton(() => HospitalsService()); locator.registerLazySingleton(() => PatientMedicalReportService()); locator.registerLazySingleton(() => LiveCarePatientServices()); + locator.registerLazySingleton(() => NavigationService()); + locator.registerLazySingleton(() => ScanQrService()); + locator.registerLazySingleton(() => SpecialClinicsService()); + locator.registerLazySingleton(() => VideoCallService()); /// View Model locator.registerFactory(() => DoctorReplayViewModel()); locator.registerFactory(() => ScheduleViewModel()); locator.registerFactory(() => ReferralPatientViewModel()); - locator.registerFactory(() => ReferredPatientViewModel()); locator.registerFactory(() => MedicineViewModel()); locator.registerFactory(() => PatientViewModel()); locator.registerFactory(() => DashboardViewModel()); @@ -120,4 +125,5 @@ void setupLocator() { locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => LiveCarePatientViewModel()); locator.registerFactory(() => PatientMedicalReportViewModel()); + locator.registerFactory(() => ScanQrViewModel()); } diff --git a/lib/main.dart b/lib/main.dart index a95378e5..c29429b0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'package:provider/provider.dart'; import './config/size_config.dart'; import './routes.dart'; import 'config/config.dart'; +import 'core/service/NavigationService.dart'; import 'core/viewModel/authentication_view_model.dart'; import 'locator.dart'; @@ -66,6 +67,7 @@ class MyApp extends StatelessWidget { dividerColor: Colors.grey[350], backgroundColor: Color.fromRGBO(255, 255, 255, 1), ), + navigatorKey: locator().navigatorKey, initialRoute: INIT_ROUTE, routes: routes, debugShowCheckedModeBanner: false, diff --git a/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart new file mode 100644 index 00000000..ec19abb0 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_List_Respose_Model.dart @@ -0,0 +1,32 @@ +class GetSpecialClinicalCareListResponseModel { + int projectID; + int clinicID; + String clinicDescription; + String clinicDescriptionN; + bool isActive; + + GetSpecialClinicalCareListResponseModel( + {this.projectID, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.isActive}); + + GetSpecialClinicalCareListResponseModel.fromJson(Map json) { + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + isActive = json['IsActive']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['IsActive'] = this.isActive; + return data; + } +} diff --git a/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart new file mode 100644 index 00000000..287f40f1 --- /dev/null +++ b/lib/models/dashboard/get_special_clinical_care_mapping_List_Respose_Model.dart @@ -0,0 +1,37 @@ +class GetSpecialClinicalCareMappingListResponseModel { + int mappingProjectID; + int clinicID; + int nursingStationID; + bool isActive; + int projectID; + String description; + + GetSpecialClinicalCareMappingListResponseModel( + {this.mappingProjectID, + this.clinicID, + this.nursingStationID, + this.isActive, + this.projectID, + this.description}); + + GetSpecialClinicalCareMappingListResponseModel.fromJson( + Map json) { + mappingProjectID = json['MappingProjectID']; + clinicID = json['ClinicID']; + nursingStationID = json['NursingStationID']; + isActive = json['IsActive']; + projectID = json['ProjectID']; + description = json['Description']; + } + + Map toJson() { + final Map data = new Map(); + data['MappingProjectID'] = this.mappingProjectID; + data['ClinicID'] = this.clinicID; + data['NursingStationID'] = this.nursingStationID; + data['IsActive'] = this.isActive; + data['ProjectID'] = this.projectID; + data['Description'] = this.description; + return data; + } +} diff --git a/lib/models/livecare/start_call_req.dart b/lib/models/livecare/start_call_req.dart index 9dabccc1..b3ceabb5 100644 --- a/lib/models/livecare/start_call_req.dart +++ b/lib/models/livecare/start_call_req.dart @@ -1,56 +1,56 @@ class StartCallReq { - int? vCID; - bool? isrecall; - String? tokenID; - String? generalid; - int? doctorId; - bool? isOutKsa; - String? projectName; - String? docotrName; - String? clincName; - String? docSpec; - int? clinicId; + String clincName; + int clinicId; + String docSpec; + String docotrName; + int doctorId; + String generalid; + bool isOutKsa; + bool isrecall; + String projectName; + String tokenID; + int vCID; StartCallReq( - {this.vCID, - this.isrecall, - this.tokenID, - this.generalid, - this.doctorId, - this.isOutKsa, - this.projectName, - this.docotrName, - this.clincName, - this.docSpec, - this.clinicId}); + {this.clincName, + this.clinicId, + this.docSpec, + this.docotrName, + this.doctorId, + this.generalid, + this.isOutKsa, + this.isrecall, + this.projectName, + this.tokenID, + this.vCID}); StartCallReq.fromJson(Map json) { - vCID = json['VC_ID']; - isrecall = json['isrecall']; - tokenID = json['TokenID']; - generalid = json['generalid']; + clincName = json['clincName']; + clinicId = json['ClinicId']; + docSpec = json['Doc_Spec']; + docotrName = json['DocotrName']; doctorId = json['DoctorId']; + generalid = json['generalid']; isOutKsa = json['IsOutKsa']; + isrecall = json['isrecall']; projectName = json['projectName']; - docotrName = json['DocotrName']; - clincName = json['clincName']; - docSpec = json['Doc_Spec']; - clinicId = json['ClinicId']; + tokenID = json['TokenID']; + vCID = json['VC_ID']; } Map toJson() { final Map data = new Map(); - data['VC_ID'] = this.vCID; - data['isrecall'] = this.isrecall; - data['TokenID'] = this.tokenID; - data['generalid'] = this.generalid; + data['clincName'] = this.clincName; + data['ClinicId'] = this.clinicId; + data['Doc_Spec'] = this.docSpec; + data['DocotrName'] = this.docotrName; data['DoctorId'] = this.doctorId; + data['generalid'] = this.generalid; data['IsOutKsa'] = this.isOutKsa; + data['isrecall'] = this.isrecall; data['projectName'] = this.projectName; - data['DocotrName'] = this.docotrName; - data['clincName'] = this.clincName; - data['Doc_Spec'] = this.docSpec; - data['ClinicId'] = this.clinicId; + data['TokenID'] = this.tokenID; + data['VC_ID'] = this.vCID; return data; } -} +} \ No newline at end of file diff --git a/lib/models/patient/my_referral/my_referred_patient_model.dart b/lib/models/patient/my_referral/my_referred_patient_model.dart index 0dad14af..dbb3a90b 100644 --- a/lib/models/patient/my_referral/my_referred_patient_model.dart +++ b/lib/models/patient/my_referral/my_referred_patient_model.dart @@ -164,8 +164,9 @@ class MyReferredPatientModel { referringDoctor = json['ReferringDoctor']; referralClinic = json['ReferralClinic']; referringClinic = json['ReferringClinic']; - referralStatus = json['ReferralStatus']; - referralDate = json['ReferralDate']; + createdOn = json['CreatedOn']; + referralStatus = json["ReferralStatus"] is String?json['ReferralStatus']== "Accepted"?46:json['ReferralStatus']=="Pending"?1:0 : json['ReferralStatus']; + referralDate = json['ReferralDate'] ?? createdOn; referringDoctorRemarks = json['ReferringDoctorRemarks']; referredDoctorRemarks = json['ReferredDoctorRemarks']; referralResponseOn = json['ReferralResponseOn']; @@ -177,7 +178,6 @@ class MyReferredPatientModel { appointmentDate = json['AppointmentDate']; appointmentType = json['AppointmentType']; patientMRN = json['PatientMRN']; - createdOn = json['CreatedOn']; clinicID = json['ClinicID']; nationalityID = json['NationalityID']; age = json['Age']; diff --git a/lib/models/patient/profile/patient_profile_app_bar_model.dart b/lib/models/patient/profile/patient_profile_app_bar_model.dart new file mode 100644 index 00000000..f4654a29 --- /dev/null +++ b/lib/models/patient/profile/patient_profile_app_bar_model.dart @@ -0,0 +1,86 @@ +import '../patiant_info_model.dart'; + +class PatientProfileAppBarModel { + double height; + bool isInpatient; + bool isDischargedPatient; + bool isFromLiveCare; + PatiantInformtion patient; + String doctorName; + String branch; + DateTime appointmentDate; + String profileUrl; + String invoiceNO; + String orderNo; + bool isPrescriptions; + bool isMedicalFile; + String episode; + String visitDate; + String clinic; + bool isAppointmentHeader; + bool isFromLabResult; + + PatientProfileAppBarModel( + {this.height = 0.0, + this.isInpatient= false, + this.isDischargedPatient= false, + this.isFromLiveCare= false, + this.patient, + this.doctorName, + this.branch, + this.appointmentDate, + this.profileUrl, + this.invoiceNO, + this.orderNo, + this.isPrescriptions= false, + this.isMedicalFile= false, + this.episode, + this.visitDate, + this.clinic, + this.isAppointmentHeader = false, + this.isFromLabResult =false}); + + PatientProfileAppBarModel.fromJson(Map json) { + height = json['height']; + isInpatient = json['isInpatient']; + isDischargedPatient = json['isDischargedPatient']; + isFromLiveCare = json['isFromLiveCare']; + patient = json['patient']; + doctorName = json['doctorName']; + branch = json['branch']; + appointmentDate = json['appointmentDate']; + profileUrl = json['profileUrl']; + invoiceNO = json['invoiceNO']; + orderNo = json['orderNo']; + isPrescriptions = json['isPrescriptions']; + isMedicalFile = json['isMedicalFile']; + episode = json['episode']; + visitDate = json['visitDate']; + clinic = json['clinic']; + isAppointmentHeader = json['isAppointmentHeader']; + isFromLabResult = json['isFromLabResult']; + } + + Map toJson() { + final Map data = new Map(); + data['height'] = this.height; + data['isInpatient'] = this.isInpatient; + data['isDischargedPatient'] = this.isDischargedPatient; + data['isFromLiveCare'] = this.isFromLiveCare; + data['patient'] = this.patient; + data['doctorName'] = this.doctorName; + data['branch'] = this.branch; + data['appointmentDate'] = this.appointmentDate; + data['profileUrl'] = this.profileUrl; + data['invoiceNO'] = this.invoiceNO; + data['orderNo'] = this.orderNo; + data['isPrescriptions'] = this.isPrescriptions; + data['isMedicalFile'] = this.isMedicalFile; + data['episode'] = this.episode; + data['visitDate'] = this.visitDate; + data['clinic'] = this.clinic; + data['isAppointmentHeader'] = this.isAppointmentHeader; + data['isFromLabResult'] = this.isFromLabResult; + return data; + } +} diff --git a/lib/root_page.dart b/lib/root_page.dart index 6b5eb09d..f7955eff 100644 --- a/lib/root_page.dart +++ b/lib/root_page.dart @@ -11,8 +11,11 @@ import 'landing_page.dart'; class RootPage extends StatelessWidget { @override Widget build(BuildContext context) { + + AuthenticationViewModel authenticationViewModel = Provider.of(context); Widget buildRoot() { + switch (authenticationViewModel.status) { case APP_STATUS.LOADING: return Scaffold( diff --git a/lib/routes.dart b/lib/routes.dart index 33aa5636..0826c76e 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,4 +1,5 @@ import 'package:doctor_app_flutter/root_page.dart'; +import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/medical-file/health_summary_page.dart'; import 'package:doctor_app_flutter/screens/patients/ECGPage.dart'; import 'package:doctor_app_flutter/screens/patients/insurance_approval_screen_patient.dart'; @@ -37,6 +38,7 @@ const String LOGIN = 'login'; const String VERIFICATION_METHODS = 'verification-methods'; const String PATIENTS = 'patients/patients'; const String PATIENTS_PROFILE = 'patients/patients-profile'; +const String PATIENTS_END_Call = 'patients/patients-profile/endCall'; const String IN_PATIENTS_PROFILE = 'inpatients/patients-profile'; const String LAB_RESULT = 'patients/lab_result'; const String HEALTH_SUMMARY = 'patients/health-summary'; @@ -88,6 +90,7 @@ var routes = { PATIENT_MEDICAL_REPORT: (_) => MedicalReportPage(), PATIENT_MEDICAL_REPORT_INSERT: (_) => AddVerifyMedicalReport(), PATIENT_MEDICAL_REPORT_DETAIL: (_) => MedicalReportDetailPage(), + PATIENTS_END_Call: (_) => EndCallScreen(), CREATE_EPISODE: (_) => UpdateSoapIndex( isUpdate: true, ), diff --git a/lib/screens/auth/login_screen.dart b/lib/screens/auth/login_screen.dart index e6d024fd..6adbbfe0 100644 --- a/lib/screens/auth/login_screen.dart +++ b/lib/screens/auth/login_screen.dart @@ -2,14 +2,11 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; -import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; @@ -25,7 +22,6 @@ class _LoginScreenState extends State { late String platformImei; bool allowCallApi = true; - //TODO change AppTextFormField to AppTextFormFieldCustom final loginFormKey = GlobalKey(); var projectIdController = TextEditingController(); var userIdController = TextEditingController(); @@ -38,134 +34,137 @@ class _LoginScreenState extends State { @override Widget build(BuildContext context) { authenticationViewModel = Provider.of(context); + double textFieldHeight = SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort ?10:SizeConfig.isHeightShort?8:6); return AppScaffold( isShowAppBar: false, backgroundColor: HexColor('#F8F8F8'), - body: SafeArea( - child: ListView(children: [ - Container( + body: SingleChildScrollView( + child: SafeArea( + child: Container( margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 30), alignment: Alignment.topLeft, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - //TODO Use App Text rather than text - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //TODO Use App Text rather than text + Container( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ SizedBox( - height: 30, + height: 10, ), - ], - ), - Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 10, - ), - Text( - TranslationBase.of(context).welcomeTo ?? "", - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, fontFamily: 'Poppins'), + Text( + TranslationBase.of(context).welcomeTo, + style: TextStyle( + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 4, + fontWeight: FontWeight.w600, + fontFamily: 'Poppins'), + ), + Text( + TranslationBase.of(context).drSulaimanAlHabib, + style: TextStyle( + color: Color(0xFF2B353E), + fontWeight: FontWeight.bold, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 6, + fontFamily: 'Poppins'), + ), + Text( + "Doctor App", + style: TextStyle( + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 4, + fontWeight: FontWeight.w600, + color: Color(0xFFD02127)), + ), + ])), + SizedBox( + height: 40, + ), + Form( + key: loginFormKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildSizedBox(), + AppTextFieldCustom( + height: textFieldHeight, + hintText: TranslationBase.of(context).enterId, + hasBorder: true, + controller: userIdController, + onChanged: (value) { + if (value != null) + setState(() { + authenticationViewModel.userInfo.userID = + value.trim(); + }); + }, ), - Text( - TranslationBase.of(context).drSulaimanAlHabib ?? "", - style: TextStyle( - color: Color(0xFF2B353E), - fontWeight: FontWeight.bold, - fontSize: SizeConfig.isMobile ? 24 : SizeConfig.realScreenWidth * 0.029, - fontFamily: 'Poppins'), + buildSizedBox(), + AppTextFieldCustom( + height: textFieldHeight, + hintText: TranslationBase.of(context).enterPassword, + hasBorder: true, + isSecure: true, + controller: passwordController, + onChanged: (value) { + if (value != null) + setState(() { + authenticationViewModel.userInfo.password = + value.trim(); + }); + this.getProjects( + authenticationViewModel.userInfo.userID); + }, + onClick: () {}, ), - Text( - "Doctor App", - style: TextStyle( - fontSize: SizeConfig.isMobile ? 16 : SizeConfig.realScreenWidth * 0.030, - fontWeight: FontWeight.w600, - color: Color(0xFFD02127)), + buildSizedBox(), + AppTextFieldCustom( + height: textFieldHeight, + hintText: + TranslationBase.of(context).selectYourProject, + hasBorder: true, + controller: projectIdController, + isTextFieldHasSuffix: true, + enabled: false, + onClick: projectsList.isEmpty== null ? null:() { + Helpers.showCupertinoPicker( + context, + projectsList, + 'facilityName', + onSelectProject, + authenticationViewModel); + }, ), + buildSizedBox(), ]), - ], - )), - SizedBox( - height: 40, - ), - Form( - key: loginFormKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: SizeConfig.realScreenWidth * 0.90, - height: SizeConfig.realScreenHeight * 0.65, - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - buildSizedBox(), - AppTextFieldCustom( - hintText: TranslationBase.of(context).enterId, - hasBorder: true, - controller: userIdController, - onChanged: (value) { - if (value != null) - setState(() { - authenticationViewModel.userInfo.userID = value.trim(); - }); - }, - ), - buildSizedBox(), - AppTextFieldCustom( - hintText: TranslationBase.of(context).enterPassword, - hasBorder: true, - isSecure: true, - controller: passwordController, - onChanged: (value) { - if (value != null) - setState(() { - authenticationViewModel.userInfo.password = value.trim(); - }); - // if(allowCallApi) { - this.getProjects(authenticationViewModel.userInfo.userID); - // setState(() { - // allowCallApi = false; - // }); - // } - }, - onClick: () {}, - ), - buildSizedBox(), - AppTextFieldCustom( - hintText: TranslationBase.of(context).selectYourProject, - hasBorder: true, - controller: projectIdController, - isTextFieldHasSuffix: true, - enabled: false, - onClick: () { - Helpers.showCupertinoPicker( - context, projectsList, 'facilityName', onSelectProject, authenticationViewModel); - }, - ), - buildSizedBox() - ]), - ), - ], - ), - ) - ], - ) - ])) - ]), + ), + SizedBox( + height: 40, + ), + ], + )), + ), ), bottomSheet: Container( - height: 90, +// color: Colors.green, + height: SizeConfig.heightMultiplier * 10, width: double.infinity, child: Center( child: FractionallySizedBox( widthFactor: 0.9, child: Column( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.center, children: [ AppButton( + height: SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 8 : 6), + hPadding: 1, title: TranslationBase.of(context).login, color: Color(0xFFD02127), fontWeight: FontWeight.w700, @@ -175,9 +174,7 @@ class _LoginScreenState extends State { login(context); }, ), - SizedBox( - height: 25, - ) + ], ), ), @@ -188,7 +185,7 @@ class _LoginScreenState extends State { SizedBox buildSizedBox() { return SizedBox( - height: 20, + height: SizeConfig.heightMultiplier * 2, ); } @@ -205,22 +202,14 @@ class _LoginScreenState extends State { } else { GifLoaderDialogUtils.hideDialog(context); authenticationViewModel.setUnverified(true, isFromLogin: true); - // Navigator.of(context).pushReplacement( - // MaterialPageRoute( - // builder: (BuildContext context) => - // VerificationMethodsScreen( - // password: authenticationViewModel.userInfo.password, - // isFromLogin: true, - // ), - // ), - // ); } } } onSelectProject(index) { setState(() { - authenticationViewModel.userInfo.projectID = projectsList[index].facilityId; + authenticationViewModel.userInfo.projectID = + projectsList[index].facilityId; projectIdController.text = projectsList[index].facilityName!; }); @@ -236,7 +225,8 @@ class _LoginScreenState extends State { if (authenticationViewModel.state == ViewState.Idle) { projectsList = authenticationViewModel.hospitals; setState(() { - authenticationViewModel.userInfo.projectID = projectsList[0].facilityId; + authenticationViewModel.userInfo.projectID = + projectsList[0].facilityId; projectIdController.text = projectsList[0].facilityName!; }); } diff --git a/lib/screens/auth/verification_methods_screen.dart b/lib/screens/auth/verification_methods_screen.dart index 03d6a6e6..f211781f 100644 --- a/lib/screens/auth/verification_methods_screen.dart +++ b/lib/screens/auth/verification_methods_screen.dart @@ -1,6 +1,5 @@ import 'dart:io' show Platform; -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; @@ -13,21 +12,15 @@ import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/secondary_button.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; -import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import '../../config/size_config.dart'; -import '../../landing_page.dart'; -import '../../root_page.dart'; -import '../../routes.dart'; import '../../util/dr_app_shared_pref.dart'; import '../../util/helpers.dart'; import '../../widgets/auth/verification_methods_list.dart'; -import 'login_screen.dart'; DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); Helpers helpers = Helpers(); @@ -63,303 +56,390 @@ class _VerificationMethodsScreenState extends State { body: SingleChildScrollView( child: Center( child: FractionallySizedBox( - child: Container( - margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0), - height: SizeConfig.realScreenHeight * .95, - width: SizeConfig.realScreenWidth, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - height: 80, - ), - if (authenticationViewModel.isFromLogin) - InkWell( - onTap: () { - authenticationViewModel.setUnverified(false, isFromLogin: false); - authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); - }, - child: Icon( - Icons.arrow_back_ios, - color: Color(0xFF2B353E), - )), - Container( - child: Column( + widthFactor: 0.9, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?6:4), + ), + if(authenticationViewModel.isFromLogin) + InkWell( + onTap: (){ + authenticationViewModel.setUnverified(false,isFromLogin: false); + authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); + }, + child: Icon(Icons.arrow_back_ios,color: Color(0xFF2B353E),) + + ), + Column( + children: [ + SizedBox( + height: SizeConfig.heightMultiplier*(SizeConfig.isHeightVeryShort?3:4), + ), + authenticationViewModel.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, children: [ + + AppText( + TranslationBase.of(context).welcomeBack, + fontSize:SizeConfig.getTextMultiplierBasedOnWidth()*4, + fontWeight: FontWeight.w700, + color: Color(0xFF2B353E), + ), + AppText( + Helpers.capitalize(authenticationViewModel.user.doctorName), + fontSize: SizeConfig.getTextMultiplierBasedOnWidth()*6, + color: Color(0xFF2B353E), + fontWeight: FontWeight.bold, + ), SizedBox( - height: 20, + height: SizeConfig.heightMultiplier*4, ), - authenticationViewModel.user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).welcomeBack, - fontSize: 12, - fontWeight: FontWeight.w700, - color: Color(0xFF2B353E), - ), - AppText( - Helpers.capitalize(authenticationViewModel.user?.doctorName), - fontSize: 24, - color: Color(0xFF2B353E), - fontWeight: FontWeight.bold, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context).accountInfo, - fontSize: 16, - color: Color(0xFF2E303A), - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 20, - ), - Container( - padding: EdgeInsets.all(15), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all( - Radius.circular(10), - ), - border: Border.all(color: HexColor('#707070'), width: 0.1), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Text( - TranslationBase.of(context).lastLoginAt!, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontFamily: 'Poppins', - fontSize: 16, - color: Color(0xFF2E303A), - fontWeight: FontWeight.w700, - ), - ), - Row( - children: [ - AppText( - TranslationBase.of(context).verifyWith, - fontSize: 14, - color: Color(0xFF575757), - fontWeight: FontWeight.w600, - ), - AppText( - authenticationViewModel.getType( - authenticationViewModel.user?.logInTypeID, context), - fontSize: 14, - color: Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - ], - ) - ], - crossAxisAlignment: CrossAxisAlignment.start, - ), - Column( - children: [ - AppText( - authenticationViewModel.user?.editedOn != null - ? AppDateUtils.getDayMonthYearDateFormatted( - AppDateUtils.convertStringToDate( - authenticationViewModel.user!.editedOn ?? "")) - : authenticationViewModel.user?.createdOn != null - ? AppDateUtils.getDayMonthYearDateFormatted( - AppDateUtils.convertStringToDate( - authenticationViewModel.user!.createdOn ?? "")) - : '--', - textAlign: TextAlign.right, - fontSize: 13, + AppText( + TranslationBase.of(context).accountInfo , + fontSize: SizeConfig.getTextMultiplierBasedOnWidth()*5, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w600, + ), + SizedBox( + height: SizeConfig.heightMultiplier*4 + ), + Container( + padding: EdgeInsets.all(15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10), + ), + border: Border.all( + color: HexColor('#707070'), + width: 0.1), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: SizeConfig.realScreenWidth * .5, + padding: EdgeInsets.all(0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context) + .lastLoginAt, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontFamily: 'Poppins', + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 4.5, color: Color(0xFF2E303A), fontWeight: FontWeight.w700, ), - AppText( - authenticationViewModel.user?.editedOn != null - ? AppDateUtils.getHour(AppDateUtils.convertStringToDate( - authenticationViewModel!.user!.editedOn ?? "")) - : authenticationViewModel.user!.createdOn != null - ? AppDateUtils.getHour(AppDateUtils.convertStringToDate( - authenticationViewModel.user!.createdOn ?? "")) - : '--', - textAlign: TextAlign.right, - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFF575757), - ) - ], - crossAxisAlignment: CrossAxisAlignment.start, - ) - ], - ), - ), - SizedBox( - height: 20, - ), - Row( - children: [ - AppText( - "Please Verify", - fontSize: 16, - color: Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - ], - ) - ], - ) - : Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - this.onlySMSBox == false - ? Container( - margin: EdgeInsets.only(bottom: 20, top: 30), - child: AppText( - TranslationBase.of(context).verifyLoginWith, - fontSize: 18, - color: Color(0xFF2E303A), - fontWeight: FontWeight.bold, - textAlign: TextAlign.left, + ), + Container( + width: MediaQuery.of(context) + .size + .width * + 0.55, + child: RichText( + text: TextSpan( + text: TranslationBase.of(context).verifyWith, + style: TextStyle( + color: Color(0xFF2B353E), + fontWeight: FontWeight.w600, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 4.5, + fontFamily: 'Poppins', + ), + children: [ + TextSpan( + text: authenticationViewModel + .getType( + authenticationViewModel + .user + .logInTypeID, + context), + style: TextStyle( + color: + Color(0xFF2B353E), + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth() * + 4.5, + fontFamily: 'Poppins', + fontWeight: + FontWeight.w700, + ), + ) + ]), ), - ) - : AppText( - TranslationBase.of(context).verifyFingerprint2, - fontSize: SizeConfig.textMultiplier * 2.5, - textAlign: TextAlign.start, ), - ]), - authenticationViewModel.user != null && isMoreOption == false - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: InkWell( - onTap: () => { - // TODO check this logic it seem it will create bug to us - authenticateUser(AuthMethodTypes.Fingerprint, true) - }, - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: SelectedAuthMethodTypesService.getMethodsTypeService( - authenticationViewModel.user!.logInTypeID!), - authenticateUser: (AuthMethodTypes authMethodType, isActive) => - authenticateUser(authMethodType, isActive), - )), + ], + crossAxisAlignment: + CrossAxisAlignment.start, ), - Expanded( - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: AuthMethodTypes.MoreOptions, - onShowMore: () { - setState(() { - isMoreOption = true; - }); - }, - )) - ]), - ]) - : Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - onlySMSBox == false - ? Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: AuthMethodTypes.Fingerprint, - authenticateUser: (AuthMethodTypes authMethodType, isActive) => - authenticateUser(authMethodType, isActive), - )), - Expanded( - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: AuthMethodTypes.FaceID, - authenticateUser: (AuthMethodTypes authMethodType, isActive) => - authenticateUser(authMethodType, isActive), - )) - ], - ) - : SizedBox(), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: AuthMethodTypes.SMS, - authenticateUser: (AuthMethodTypes authMethodType, isActive) => - authenticateUser(authMethodType, isActive), - )), - Expanded( - child: VerificationMethodsList( - authenticationViewModel: authenticationViewModel, - authMethodType: AuthMethodTypes.WhatsApp, - authenticateUser: (AuthMethodTypes authMethodType, isActive) => - authenticateUser(authMethodType, isActive), - )) - ], ), - ]), + Column( + mainAxisAlignment: MainAxisAlignment.start, + + children: [ + AppText( + authenticationViewModel + .user.editedOn != + null + ? AppDateUtils + .getDayMonthYearDateFormatted( + AppDateUtils + .convertStringToDate( + authenticationViewModel + .user + .editedOn)) + : authenticationViewModel + .user.createdOn != + null + ? AppDateUtils.getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() *4.5, + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700, + ), + AppText( + authenticationViewModel.user.editedOn != + null + ? AppDateUtils.getHour( + AppDateUtils.convertStringToDate( + authenticationViewModel.user + .editedOn)) + : authenticationViewModel.user.createdOn != + null + ? AppDateUtils.getHour( + AppDateUtils.convertStringToDate(authenticationViewModel.user + .createdOn)) + : '--', + textAlign: + TextAlign.right, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() *4.5, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ) + ], + crossAxisAlignment: CrossAxisAlignment.start, + + ) + ], + ), + ), + SizedBox( + height: SizeConfig.heightMultiplier*3, + ), - // ) + Row( + children: [ + + //todo add translation + AppText( + "Please Verify", + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 5, + color: Color(0xFF2B353E), + + fontWeight: FontWeight.w700, + ), + ], + ), + SizedBox( + height: SizeConfig.heightMultiplier*2, + ), ], - ), - ), - ], - ), + ) + : Column( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + this.onlySMSBox == false + ? Container( + margin: EdgeInsets.only(bottom: 20, top: 30), + child: AppText( + TranslationBase.of(context) + .verifyLoginWith , + fontSize: SizeConfig.getTextMultiplierBasedOnWidth()* 4 , + color: Color(0xFF2E303A), + fontWeight: FontWeight.bold, + textAlign: TextAlign.left, + ), + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: + SizeConfig.getTextMultiplierBasedOnWidth()* 4, + textAlign: TextAlign.start, + ), + ]), + authenticationViewModel.user != null && isMoreOption == false + ? Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => + { + // TODO check this logic it seem it will create bug to us + authenticateUser( + AuthMethodTypes + .Fingerprint, true) + }, + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: SelectedAuthMethodTypesService + .getMethodsTypeService( + authenticationViewModel.user + .logInTypeID), + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + ), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.MoreOptions, + onShowMore: () { + setState(() { + isMoreOption = true; + }); + }, + )) + ]), + ]) + : Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + onlySMSBox == false + ? Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.Fingerprint, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.FaceID, + authenticateUser: + (AuthMethodTypes + authMethodType, + isActive) => + authenticateUser( + authMethodType, + isActive), + )) + ], + ) + : SizedBox(), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: AuthMethodTypes + .SMS, + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )), + Expanded( + child: VerificationMethodsList( + authenticationViewModel:authenticationViewModel, + authMethodType: + AuthMethodTypes.WhatsApp, + authenticateUser: + ( + AuthMethodTypes authMethodType, + isActive) => + authenticateUser( + authMethodType, isActive), + )) + ], + ), + ]), + + // ) + ], + ), + ], ), ), ), ), - bottomSheet: authenticationViewModel.user == null - ? SizedBox( - height: 0, - ) - : Container( - height: 90, - width: double.infinity, - child: Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SecondaryButton( - label: TranslationBase.of(context).useAnotherAccount!, - color: Color(0xFFD02127), - //fontWeight: FontWeight.w700, - onTap: () { - authenticationViewModel.deleteUser(); - authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); - // Navigator.pushAndRemoveUntil( - // AppGlobal.CONTEX, - // FadePage( - // page: RootPage(), - // ), - // (r) => false); - // Navigator.of(context).pushNamed(LOGIN); - }, - ), - SizedBox( - height: 25, - ) - ], - ), + bottomSheet: authenticationViewModel.user == null ? SizedBox(height: 0,) : Container( + // color: Colors.green, + height: SizeConfig.heightMultiplier * 10 , + width: double.infinity, + child: Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppButton( + title: TranslationBase + .of(context) + .useAnotherAccount, + color: Color(0xFFD02127), + + fontWeight: FontWeight.w700, + height: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort? 8 : 6), + hPadding: 1, + + onPressed: () { + authenticationViewModel.deleteUser(); + authenticationViewModel.setAppStatus(APP_STATUS.UNAUTHENTICATED); + }, ), - ), + + ], ), + ), + ),), ); } diff --git a/lib/screens/home/dashboard_referral_patient.dart b/lib/screens/home/dashboard_referral_patient.dart new file mode 100644 index 00000000..0b9e6765 --- /dev/null +++ b/lib/screens/home/dashboard_referral_patient.dart @@ -0,0 +1,195 @@ + +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/guage_chart.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/row_count.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; +import 'package:flutter/material.dart'; + +import 'label.dart'; + +class DashboardReferralPatient extends StatelessWidget { + final List dashboardItemList; + final double height; + final DashboardViewModel model; + + const DashboardReferralPatient({Key key, this.dashboardItemList, this.height, this.model}) : super(key: key); + @override + Widget build(BuildContext context) { + return RoundedContainer( + raduis: 16, + showBorder: false, + borderColor: Colors.white, + shadowWidth: 0.2, + shadowSpreadRadius: 3, + shadowDy: 1, + margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), + child: + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + + children: [ + Expanded( + flex: 1, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + Expanded( + flex: 4, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: SizeConfig + .getHeightMultiplier( + height: height) * + (SizeConfig.isHeightVeryShort + ? 3 + : SizeConfig.isHeightShort + ? 2 + : 2) + ), + Label(firstLine: TranslationBase + .of(context) + .patients, + secondLine: TranslationBase + .of(context) + .referral, + color: Color(0xFF2B353E), + secondLineFontSize: SizeConfig + .getHeightMultiplier( + height: height) * + (SizeConfig.isHeightVeryShort + ? 5 + : SizeConfig.isHeightShort + ? 7 + : 12),), + + SizedBox( + height: SizeConfig + .getHeightMultiplier( + height: height) * + (SizeConfig.isHeightVeryShort + ? 5 + : SizeConfig.isHeightShort + ? 10 + : 5) + ) + ], + ),), + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RowCounts( + dashboardItemList[2] + .summaryoptions[0] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[0] + .value, + Colors.black, height: height,), + RowCounts( + dashboardItemList[2] + .summaryoptions[1] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[1] + .value, + Colors.grey, height: height,), + RowCounts( + + dashboardItemList[2] + .summaryoptions[2] + .kPIParameter, + dashboardItemList[2] + .summaryoptions[2] + .value, + Colors.red, height: height,), + ], + ), + ) + ], + )), + ), + Expanded( + flex: 3, + child: Stack(children: [ + Container( + padding:EdgeInsets.all(0), + + child: GaugeChart( + _createReferralData(dashboardItemList))), + Positioned( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + AppText( + model + .getPatientCount(dashboardItemList[2]) + .toString(), + fontSize: SizeConfig.textMultiplier * 3.0, + fontWeight: FontWeight.bold, + ) + ], + ), + top: height * (SizeConfig.isHeightVeryShort?0.35:0.40), + left: 0, + right: 0) + ]), + ), + ], + )), + ])); + } + static List> _createReferralData(List dashboardItemList) { + final data = [ + new GaugeSegment( + dashboardItemList[2].summaryoptions[0].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[0].value), + charts.MaterialPalette.black), + new GaugeSegment( + dashboardItemList[2].summaryoptions[1].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[1].value), + charts.MaterialPalette.gray.shadeDefault), + new GaugeSegment( + dashboardItemList[2].summaryoptions[2].kPIParameter, + getValue(dashboardItemList[1].summaryoptions[2].value), + charts.MaterialPalette.red.shadeDefault), + ]; + + return [ + new charts.Series( + id: 'Segments', + domainFn: (GaugeSegment segment, _) => segment.segment, + measureFn: (GaugeSegment segment, _) => segment.size, + data: data, + colorFn: (GaugeSegment segment, _) => segment.color, + ) + ]; + } + + static int getValue(value) { + return value == 0 ? 1 : value; + } + +} \ No newline at end of file diff --git a/lib/screens/home/dashboard_slider-item-widget.dart b/lib/screens/home/dashboard_slider-item-widget.dart index 92089f4c..0d1a0e73 100644 --- a/lib/screens/home/dashboard_slider-item-widget.dart +++ b/lib/screens/home/dashboard_slider-item-widget.dart @@ -1,9 +1,11 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/activity_button.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/widgets/dashboard/activity_card.dart'; import 'package:flutter/material.dart'; +import 'label.dart'; + class DashboardSliderItemWidget extends StatelessWidget { final DashboardModel item; @@ -13,22 +15,22 @@ class DashboardSliderItemWidget extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - Row( + Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - AppText( - item.kPIName, - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - ), + Label(firstLine:Helpers.getLabelFromKPI(item.kPIName) ,secondLine:Helpers.getNameFromKPI(item.kPIName), ), + ], ), - new Container( - height: 110, + + + + new Container( + height: SizeConfig.heightMultiplier* (SizeConfig.isHeightVeryShort?16:SizeConfig.isHeightShort?14:SizeConfig.isHeightLarge?15:13), child: ListView( scrollDirection: Axis.horizontal, children: List.generate(item.summaryoptions!.length, (int index) { - return GetActivityButton(item.summaryoptions![index]); + return GetActivityCard(item.summaryoptions![index]); }))) ], ); diff --git a/lib/screens/home/dashboard_swipe_widget.dart b/lib/screens/home/dashboard_swipe_widget.dart index 2e7815ba..5e45c9b4 100644 --- a/lib/screens/home/dashboard_swipe_widget.dart +++ b/lib/screens/home/dashboard_swipe_widget.dart @@ -1,16 +1,13 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/guage_chart.dart'; import 'package:doctor_app_flutter/widgets/dashboard/out_patient_stack.dart'; -import 'package:doctor_app_flutter/widgets/dashboard/row_count.dart'; import 'package:doctor_app_flutter/widgets/dashboard/swiper_rounded_pagination.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; -import 'package:charts_flutter/flutter.dart' as charts; + +import 'dashboard_referral_patient.dart'; class DashboardSwipeWidget extends StatefulWidget { final List dashboardItemList; @@ -28,8 +25,10 @@ class _DashboardSwipeWidgetState extends State { @override Widget build(BuildContext context) { + double height = SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 40 : SizeConfig.isHeightLarge?33:31); return Container( - height: MediaQuery.of(context).size.height * 0.35, + height: height, // height: 230, child: Swiper( onIndexChanged: (index) { @@ -41,10 +40,10 @@ class _DashboardSwipeWidgetState extends State { } }, itemBuilder: (BuildContext context, int index) { - return getSwipeWidget(widget.dashboardItemList, index); + return getSwipeWidget(widget.dashboardItemList, index, height); }, itemCount: 3, - // itemHeight: 300, + pagination: new SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) { return new Stack( alignment: Alignment.bottomCenter, @@ -77,21 +76,24 @@ class _DashboardSwipeWidgetState extends State { ); } - Widget getSwipeWidget(List dashboardItemList, int index) { + Widget getSwipeWidget(List dashboardItemList, int index, double height) { if (index == 1) return RoundedContainer( - raduis: 16, - showBorder: true, + raduis: 16, + showBorder: false, borderColor: Colors.white, shadowWidth: 0.2, shadowSpreadRadius: 3, shadowDy: 1, margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), - child: Padding(padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[1]))); + child: Padding(padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[1], + ), + ), + ); if (index == 0) return RoundedContainer( raduis: 16, - showBorder: true, + showBorder: false, borderColor: Colors.white, shadowWidth: 0.2, shadowSpreadRadius: 3, @@ -99,118 +101,12 @@ class _DashboardSwipeWidgetState extends State { margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), child: Padding(padding: const EdgeInsets.all(5.0), child: GetOutPatientStack(dashboardItemList[0]))); if (index == 2) - return RoundedContainer( - raduis: 16, - showBorder: true, - borderColor: Colors.white, - shadowWidth: 0.2, - shadowSpreadRadius: 3, - shadowDy: 1, - margin: EdgeInsets.only(top: 15, bottom: 15, left: 10, right: 10), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - flex: 1, - child: Row( - children: [ - Expanded( - flex: 4, - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(8), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).patients, - fontSize: 12, - fontWeight: FontWeight.bold, - fontHeight: 0.5, - ), - AppText( - TranslationBase.of(context).referral, - fontSize: 22, - fontWeight: FontWeight.bold, - ), - ], - )), - Expanded( - flex: 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: RowCounts(dashboardItemList[2].summaryoptions![0].kPIParameter, - dashboardItemList[2].summaryoptions![0].value!, Colors.black), - ), - Expanded( - child: RowCounts(dashboardItemList[2].summaryoptions![1].kPIParameter, - dashboardItemList[2].summaryoptions![1].value!, Colors.grey), - ), - Expanded( - child: RowCounts(dashboardItemList[2].summaryoptions![2].kPIParameter, - dashboardItemList[2].summaryoptions![2].value!, Colors.red), - ), - ], - ), - ) - ], - )), - ), - Expanded( - flex: 3, - child: Stack(children: [ - Container(child: GaugeChart(_createReferralData(widget.dashboardItemList))), - Positioned( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - AppText( - widget.model.getPatientCount(dashboardItemList[2]).toString(), - fontSize: SizeConfig.textMultiplier * 3.0, - fontWeight: FontWeight.bold, - ) - ], - ), - top: MediaQuery.of(context).size.height * 0.13, - left: 0, - right: 0) - ]), - ), - ], - )), - ])); + return DashboardReferralPatient(dashboardItemList: widget.dashboardItemList,height: height,model: widget.model,); return Container(); } - static List> _createReferralData(List dashboardItemList) { - final data = [ - new GaugeSegment(dashboardItemList[2].summaryoptions![0].kPIParameter!, - getValue(dashboardItemList[1].summaryoptions![0].value), charts.MaterialPalette.black), - new GaugeSegment(dashboardItemList[2].summaryoptions![1].kPIParameter!, - getValue(dashboardItemList[1].summaryoptions![1].value), charts.MaterialPalette.gray.shadeDefault), - new GaugeSegment(dashboardItemList[2].summaryoptions![2].kPIParameter!, - getValue(dashboardItemList[1].summaryoptions![2].value), charts.MaterialPalette.red.shadeDefault), - ]; - return [ - new charts.Series( - id: 'Segments', - domainFn: (GaugeSegment segment, _) => segment.segment, - measureFn: (GaugeSegment segment, _) => segment.size, - data: data, - colorFn: (GaugeSegment segment, _) => segment.color, - ) - ]; - } - static int getValue(value) { - return value == 0 ? 1 : value; - } } + + diff --git a/lib/screens/home/home_page_card.dart b/lib/screens/home/home_page_card.dart index c4743f3b..2dac78b9 100644 --- a/lib/screens/home/home_page_card.dart +++ b/lib/screens/home/home_page_card.dart @@ -10,7 +10,7 @@ class HomePageCard extends StatelessWidget { Key? key, required this.color, this.opacity = 0.4, - required this.margin}) + required this.margin, this.width}) : super(key: key); final bool hasBorder; final String? imageName; @@ -18,16 +18,16 @@ class HomePageCard extends StatelessWidget { final GestureTapCallback onTap; final Color color; final double opacity; + final double width; final EdgeInsets margin; @override Widget build(BuildContext context) { return InkWell( onTap: onTap, child: Container( - width: 120, - height: MediaQuery.of(context).orientation == Orientation.portrait ? 100 : 200, + width: width, margin: this.margin, - decoration: BoxDecoration( + decoration: BoxDecoration( color: !hasBorder ? color != null ? color diff --git a/lib/screens/home/home_patient_card.dart b/lib/screens/home/home_patient_card.dart index f0bee0cb..798b73cd 100644 --- a/lib/screens/home/home_patient_card.dart +++ b/lib/screens/home/home_patient_card.dart @@ -10,6 +10,7 @@ class HomePatientCard extends StatelessWidget { final String text; final Color textColor; final GestureTapCallback onTap; + final double iconSize; HomePatientCard({ required this.backgroundColor, @@ -18,13 +19,17 @@ class HomePatientCard extends StatelessWidget { required this.text, required this.textColor, required this.onTap, + this.iconSize = 30, }); @override Widget build(BuildContext context) { + double width = SizeConfig.heightMultiplier* + (SizeConfig.isHeightVeryShort ? 16 : SizeConfig.isHeightLarge?15:13); return HomePageCard( color: backgroundColor, - margin: EdgeInsets.all(4), + width: width, + margin: EdgeInsets.all(SizeConfig.widthMultiplier *1.121), child: Container( padding: EdgeInsets.all(8), child: Column( @@ -35,13 +40,14 @@ class HomePatientCard extends StatelessWidget { child: Stack( children: [ Positioned( - bottom: 0.1, - right: 0.5, - width: 23.0, - height: 25.0, + top: SizeConfig.isHeightVeryShort ? 8 : 8, + left: SizeConfig.isHeightVeryShort ? 5 : 10, + width: SizeConfig.getWidthMultiplier(width: width) * 10, + height: SizeConfig.getWidthMultiplier(width: width) * 15, child: Icon( cardIcon, - size: 60, + size: SizeConfig.getWidthMultiplier(width: width) * + (SizeConfig.isHeightVeryShort ? 45 : 60), color: backgroundIconColor, ), ), @@ -52,7 +58,8 @@ class HomePatientCard extends StatelessWidget { children: [ Icon( cardIcon, - size: 30, + size: + SizeConfig.getWidthMultiplier(width: width) * 22, color: textColor, ), SizedBox( @@ -70,7 +77,9 @@ class HomePatientCard extends StatelessWidget { text, color: textColor, textAlign: TextAlign.start, - fontSize: SizeConfig.textMultiplier * 1.6, + fontSize: + SizeConfig.getTextMultiplierBasedOnWidth(width: width) * + (SizeConfig.isHeightVeryShort ? 11 : 10), ), ), ), diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index e5c08cbc..d0fb3569 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -1,14 +1,10 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; -import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; -import 'package:doctor_app_flutter/models/patient/patient_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_slider-item-widget.dart'; import 'package:doctor_app_flutter/screens/home/dashboard_swipe_widget.dart'; @@ -20,20 +16,15 @@ import 'package:doctor_app_flutter/screens/patients/out_patient/out_patient_scre import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/patient_referral_screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/profile-welcome-widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:sticky_headers/sticky_headers/widget.dart'; -import '../../widgets/shared/app_texts_widget.dart'; +import 'home_screen_header.dart'; +import 'label.dart'; class HomeScreen extends StatefulWidget { HomeScreen({Key? key, this.title}) : super(key: key); @@ -47,15 +38,16 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { bool isLoading = false; - late ProjectViewModel projectsProvider; - var _isInit = true; - late DoctorProfileModel profile; + ProjectViewModel projectsProvider; + DoctorProfileModel profile; bool isExpanded = false; bool isInpatient = false; int sliderActiveIndex = 0; - var clinicId; + String clinicId; late AuthenticationViewModel authenticationViewModel; int colorIndex = 0; + final GlobalKey scaffoldKey = new GlobalKey(); + @override Widget build(BuildContext context) { @@ -68,222 +60,137 @@ class _HomeScreenState extends State { } return BaseView( + onModelReady: (model) async { await model.setFirebaseNotification(projectsProvider, authenticationViewModel); await model.getDashboard(); await model.getDoctorProfile(isGetProfile: true); await model.checkDoctorHasLiveCare(); + // await model.getSpecialClinicalCareList(); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - isShowAppBar: false, + isShowAppBar: true, + appBar: HomeScreenHeader( + model: model, + onOpenDrawer: (){ + Scaffold.of(context).openDrawer(); + }, + ), body: ListView(children: [ Column(children: [ - StickyHeader( - header: Container( - color: Colors.grey[100], - padding: EdgeInsets.only(top: 10), - child: Stack(children: [ - IconButton( - icon: Image.asset('assets/images/menu.png', height: 50, width: 50), - iconSize: 18, - color: Colors.black, - onPressed: () => Scaffold.of(context).openDrawer(), - ), - Column(children: [ - ProfileWelcomeWidget( - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width * .6, - child: projectsProvider.doctorClinicsList.length > 0 - ? Stack( - children: [ - DropdownButtonHideUnderline( - child: DropdownButton( - dropdownColor: Colors.white, - iconEnabledColor: Colors.black, - isExpanded: true, - value: clinicId == null - ? projectsProvider.doctorClinicsList[0].clinicID - : clinicId, - iconSize: 25, - elevation: 16, - selectedItemBuilder: (BuildContext context) { - return projectsProvider.doctorClinicsList.map((item) { - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: EdgeInsets.all(2), - margin: EdgeInsets.all(2), - decoration: new BoxDecoration( - color: Colors.red[800], - borderRadius: BorderRadius.circular(20), - ), - constraints: BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: Center( - child: AppText( - projectsProvider.doctorClinicsList.length.toString(), - color: Colors.white, - fontSize: projectsProvider.isArabic ? 10 : 11, - textAlign: TextAlign.center, - ), - )), - ], - ), - AppText(item.clinicName, - fontSize: 12, - color: Colors.black, - fontWeight: FontWeight.bold, - textAlign: TextAlign.end), - ], - ); - }).toList(); - }, - onChanged: (newValue) async { - clinicId = newValue; - GifLoaderDialogUtils.showMyDialog(context); - await model.changeClinic(clinicId, authenticationViewModel); - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - }, - items: projectsProvider.doctorClinicsList.map((item) { - return DropdownMenuItem( - child: AppText( - item.clinicName, - textAlign: TextAlign.left, - ), - value: item.clinicID, - ); - }).toList(), - )), - ], - ) - : AppText(TranslationBase.of(context).noClinic), - ), - ], - ), - isClinic: true, - height: 50, - ), - ]) - ])), - content: Column( - children: [ - model.dashboardItemsList.length > 0 - ? DashboardSwipeWidget( - model.dashboardItemsList, - model, - (sliderIndex) { - setState(() { - sliderActiveIndex = sliderIndex; - }); - }, - ) - : SizedBox(), - model.dashboardItemsList.length > 0 - ? FractionallySizedBox( - widthFactor: 0.90, - child: Container( - child: Column(mainAxisAlignment: MainAxisAlignment.start, children: [ - SizedBox( - height: 10, - ), - sliderActiveIndex == 1 - ? DashboardSliderItemWidget(model.dashboardItemsList[4]) - : sliderActiveIndex == 0 - ? DashboardSliderItemWidget(model.dashboardItemsList[3]) - : DashboardSliderItemWidget(model.dashboardItemsList[6]), - ]))) - : SizedBox(), - FractionallySizedBox( - // widthFactor: 0.90, + // SizedBox( + // height: SizeConfig.heightMultiplier * 1.4, + // ), + model.dashboardItemsList.length > 0 + ? DashboardSwipeWidget( + model.dashboardItemsList, + model, + (sliderIndex) { + setState(() { + sliderActiveIndex = sliderIndex; + }); + }, + ) + : SizedBox(), + + // SizedBox( + // height: SizeConfig.heightMultiplier * 1.4, + // ), + model.dashboardItemsList.length > 0 + ? FractionallySizedBox( + widthFactor: 0.94, child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(50), - )), - padding: EdgeInsets.only(left: 20, top: 10, right: 20), - margin: EdgeInsets.only(top: 10), child: Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - height: 10, - ), - Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).patients, - fontSize: 12, - fontWeight: FontWeight.bold, - fontHeight: .5, - ), - AppText( - TranslationBase.of(context).services, - fontSize: 22, - fontWeight: FontWeight.bold, - ), - ], - )), - SizedBox( - height: 10, - ), - Container( - height: 120, - child: ListView(scrollDirection: Axis.horizontal, children: [ - ...homePatientsCardsWidget(model), - ])), - SizedBox( - height: 20, + height: SizeConfig.heightMultiplier * 3, ), + sliderActiveIndex == 1 + ? DashboardSliderItemWidget( + model.dashboardItemsList[4]) + : sliderActiveIndex == 0 + ? DashboardSliderItemWidget( + model.dashboardItemsList[3]) + : DashboardSliderItemWidget( + model.dashboardItemsList[6]), ], ), ), - ), - ], + ) + : SizedBox(), + SizedBox( + height: SizeConfig.heightMultiplier * 1.4, + ), + FractionallySizedBox( + // widthFactor: 0.90, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(70), + )), + padding: EdgeInsets.only(left: SizeConfig.widthMultiplier * 3.1, top: 10, right: SizeConfig.widthMultiplier * 3.1), + margin: EdgeInsets.only(top: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: SizeConfig.heightMultiplier * 1, + ), + Container( + child: Label( + firstLine: TranslationBase.of(context).patients, + secondLine: TranslationBase.of(context).services, + )), + SizedBox( + height: SizeConfig.heightMultiplier * .6, + ), + Container( + height: SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort + ? 16 + : SizeConfig.isHeightShort + ? 14 + : SizeConfig.isHeightLarge?15:13), + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + ...homePatientsCardsWidget(model, projectsProvider), + ], + ), + ), + SizedBox(height: SizeConfig.heightMultiplier* (SizeConfig.isHeightVeryShort?3:SizeConfig.isHeightShort?4:2)) + + ], + ), ), - ) + ), ]), ]), ), ); } - List homePatientsCardsWidget(DashboardViewModel model) { + List homePatientsCardsWidget(DashboardViewModel model,projectsProvider) { colorIndex = 0; - List backgroundColors = []; - backgroundColors.add(Color(0xffD02127)); - backgroundColors.add(Colors.grey[300]!); - backgroundColors.add(Color(0xff2B353E)); - - List backgroundIconColors = []; - backgroundIconColors.add(Colors.white12); - backgroundIconColors.add(Colors.white38); - backgroundIconColors.add(Colors.white10); + List backgroundColors = List(3); + backgroundColors[0] = Color(0xffD02127); + backgroundColors[1] = Colors.grey[300]; + backgroundColors[2] = Color(0xff2B353E); + List backgroundIconColors = List(3); + backgroundIconColors[0] = Colors.white12; + backgroundIconColors[1] = Colors.white38; + backgroundIconColors[2] = Colors.white10; + List textColors = List(3); + textColors[0] = Colors.white; + textColors[1] = Color(0xFF353E47); + textColors[2] = Colors.white; - List textColors = []; - textColors.add(Colors.white); - textColors.add(Colors.black); - textColors.add(Colors.white); - List patientCards = []; + List patientCards = List(); if (model.hasVirtualClinic) { patientCards.add(HomePatientCard( @@ -291,6 +198,7 @@ class _HomeScreenState extends State { backgroundIconColor: backgroundIconColors[colorIndex], cardIcon: DoctorApp.livecare, textColor: textColors[colorIndex], + iconSize: 21, text: "${TranslationBase.of(context).liveCare}\n${TranslationBase.of(context).patients}", onTap: () { Navigator.push( @@ -314,7 +222,8 @@ class _HomeScreenState extends State { Navigator.push( context, FadePage( - page: PatientInPatientScreen(), + page: PatientInPatientScreen(specialClinic: model.getSpecialClinic(clinicId??projectsProvider + .doctorClinicsList[0].clinicID),), ), ); }, @@ -401,3 +310,6 @@ class _HomeScreenState extends State { } } } + + + diff --git a/lib/screens/home/home_screen_header.dart b/lib/screens/home/home_screen_header.dart new file mode 100644 index 00000000..7284b659 --- /dev/null +++ b/lib/screens/home/home_screen_header.dart @@ -0,0 +1,219 @@ +// ignore: must_be_immutable +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/profile-welcome-widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.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'; + +// ignore: must_be_immutable +class HomeScreenHeader extends StatefulWidget with PreferredSizeWidget { + + final DashboardViewModel model; + final Function onOpenDrawer; + + double height = SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 10 : 6); + + HomeScreenHeader({Key key, this.model, this.onOpenDrawer}) : super(key: key); + + @override + _HomeScreenHeaderState createState() => _HomeScreenHeaderState(); + + @override + Size get preferredSize => Size(double.maxFinite,height); +} + +class _HomeScreenHeaderState extends State { + ProjectViewModel projectsProvider; + int clinicId; + + + AuthenticationViewModel authenticationViewModel; + + + @override + Widget build(BuildContext context) { + ProjectViewModel projectsProvider = Provider.of(context); + authenticationViewModel = Provider.of(context); + + return widget.model.state == ViewState.Busy + ? Container(color: Colors.grey.withOpacity(0.65)) + : Container( + color: Colors.grey[100], + child: Stack(children: [ + IconButton( + icon: Icon(FontAwesomeIcons.ellipsisH), + iconSize: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?4: 3), + color: Colors.black, + onPressed: () { + widget.onOpenDrawer(); + }, + ), + Column( + children: [ + ProfileWelcomeWidget( + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + width: MediaQuery + .of(context) + .size + .width * .6, + child: projectsProvider.doctorClinicsList.length > + 0 + ? Stack( + children: [ + DropdownButtonHideUnderline( + child: DropdownButton( + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: clinicId == null + ? projectsProvider + .doctorClinicsList[0].clinicID + : clinicId, + iconSize: SizeConfig.widthMultiplier * 7, + elevation: 16, + selectedItemBuilder: + (BuildContext context) { + return projectsProvider + .doctorClinicsList + .map((item) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + padding: + EdgeInsets.all(2), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: + Colors.red[800], + borderRadius: + BorderRadius + .circular( + 20), + ), + constraints: + BoxConstraints( + minWidth: SizeConfig + .getHeightMultiplier( + height: widget.height) * + 35, + minHeight: SizeConfig + .getHeightMultiplier( + height: widget.height) * + 30, + ), + child: Center( + child: AppText( + projectsProvider + .doctorClinicsList + .length + .toString(), + color: + Colors.white, + fontSize: + projectsProvider + .isArabic + ? SizeConfig + .getHeightMultiplier( + height: widget.height) + : SizeConfig + .getHeightMultiplier( + height: widget + .height) * 20, + textAlign: + TextAlign + .center, + ), + )), + ], + ), + AppText(item.clinicName, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth( + width: MediaQuery + .of(context) + .size + .width * .6) * (SizeConfig.isWidthLarge?4:5), + color: Color(0xFF2B353E), + maxLines: 1, + maxLength: 2, + letterSpacing: -0.96, + textOverflow: TextOverflow + .ellipsis, + fontWeight: + FontWeight.bold, + textAlign: TextAlign.end), + ], + ); + }).toList(); + }, + onChanged: (newValue) async { + setState(() { + clinicId = newValue; + }); + + GifLoaderDialogUtils.showMyDialog( + context); + await widget.model.changeClinic(newValue, + authenticationViewModel); + GifLoaderDialogUtils.hideDialog( + context); + if (widget.model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + widget.model.error); + } + }, + items: projectsProvider + .doctorClinicsList + .map((item) { + return DropdownMenuItem( + child: AppText( + item.clinicName, + textAlign: TextAlign.left, + ), + value: item.clinicID, + ); + }).toList(), + )), + ], + ) + : AppText( + TranslationBase + .of(context) + .noClinic), + ), + ], + ), + isClinic: true, + height: widget.height, + ), + ]) + ])); + } + + +} \ No newline at end of file diff --git a/lib/screens/home/label.dart b/lib/screens/home/label.dart new file mode 100644 index 00000000..7e853323 --- /dev/null +++ b/lib/screens/home/label.dart @@ -0,0 +1,45 @@ +// ignore: must_be_immutable + +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +// ignore: must_be_immutable +class Label extends StatelessWidget { + Label({ + Key key, this.firstLine, this.secondLine, this.color= const Color(0xFF2E303A), this.secondLineFontSize, this.firstLineFontSize, + }) : super(key: key); + final String firstLine; + final String secondLine; + Color color; + final double secondLineFontSize; + final double firstLineFontSize; + + @override + Widget build(BuildContext context) { + + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + firstLine, + fontSize: firstLineFontSize??SizeConfig.getTextMultiplierBasedOnWidth() *(SizeConfig.isWidthLarge?2:3) , + // fontWeight: FontWeight.bold, + color: color, + fontHeight: .5, + letterSpacing: -0.72, + fontWeight: FontWeight.w600, + ), + AppText( + secondLine, + color: color, + fontSize: secondLineFontSize??SizeConfig.getTextMultiplierBasedOnWidth() * (SizeConfig.isWidthLarge?4:6.40), + fontWeight: FontWeight.bold, + letterSpacing: -1.44, + + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/screens/live_care/end_call_screen.dart b/lib/screens/live_care/end_call_screen.dart index 38d0089a..19bc2a92 100644 --- a/lib/screens/live_care/end_call_screen.dart +++ b/lib/screens/live_care/end_call_screen.dart @@ -1,9 +1,11 @@ import 'package:doctor_app_flutter/config/config.dart'; +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/live_care/live-care_transfer_to_admin.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/PatientProfileCardModel.dart'; @@ -12,7 +14,7 @@ import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/PatientProfileButton.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -24,7 +26,7 @@ import 'package:hexcolor/hexcolor.dart'; class EndCallScreen extends StatefulWidget { final PatiantInformtion patient; - const EndCallScreen({Key? key, required this.patient}) : super(key: key); + const EndCallScreen({Key? key, required this.patient,}) : super(key: key); @override _EndCallScreenState createState() => _EndCallScreenState(); @@ -32,7 +34,7 @@ class EndCallScreen extends StatefulWidget { class _EndCallScreenState extends State { bool isInpatient = false; - + PatiantInformtion patient; bool isDischargedPatient = false; bool isSearchAndOut = false; late String patientType; @@ -41,15 +43,31 @@ class _EndCallScreenState extends State { late String to; late LiveCarePatientViewModel liveCareModel; + @override + void initState() { + super.initState(); + if(widget.patient!=null) + patient = widget.patient; + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + final routeArgs = ModalRoute.of(context).settings.arguments as Map; + if(routeArgs.containsKey('patient')) + patient = routeArgs['patient']; + } @override Widget build(BuildContext context) { final List cardsList = [ PatientProfileCardModel( TranslationBase.of(context).resume!, TranslationBase.of(context).theCall!, '', 'patient/vital_signs.png', - isInPatient: isInpatient, onTap: () async { + isInPatient: isInpatient, + color: Colors.green[800], + onTap: () async { GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.startCall(isReCall: false, vCID: widget.patient.vcId!).then((value) async { + await liveCareModel.startCall(isReCall: false, vCID: patient.vcId!).then((value) async { await liveCareModel.getDoctorProfile(); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { @@ -59,7 +77,8 @@ class _EndCallScreenState extends State { kToken: liveCareModel.startCallRes.openTokenID, kSessionId: liveCareModel.startCallRes.openSessionID, kApiKey: '46209962', - vcId: widget.patient.vcId, + vcId: patient.vcId, + patientName: patient.fullName ?? (patient.firstName != null ? "${patient.firstName} ${patient.lastName}" : "-"), tokenID: await liveCareModel.getToken(), generalId: GENERAL_ID, doctorId: liveCareModel.doctorProfile!.doctorID, @@ -70,10 +89,10 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId!, + patient.vcId!, false, - ); - GifLoaderDialogUtils.hideDialog(context); + + );GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } @@ -82,7 +101,7 @@ class _EndCallScreenState extends State { GifLoaderDialogUtils.showMyDialog(context); GifLoaderDialogUtils.showMyDialog(context); await liveCareModel.endCall( - widget.patient.vcId!, + patient.vcId!, sessionStatusModel.sessionStatus == 3, ); GifLoaderDialogUtils.hideDialog(context); @@ -98,34 +117,60 @@ class _EndCallScreenState extends State { }, isDartIcon: true, dartIcon: DoctorApp.call), PatientProfileCardModel( TranslationBase.of(context).endLC!, TranslationBase.of(context).consultation!, '', 'patient/vital_signs.png', - isInPatient: isInpatient, onTap: () { + isInPatient: isInpatient, + color: Colors.red[800], + onTap: () { Helpers.showConfirmationDialog(context, "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).endLC} ${TranslationBase.of(context).consultation} ?", () async { Navigator.of(context).pop(); GifLoaderDialogUtils.showMyDialog(context); - await liveCareModel.endCallWithCharge(widget.patient.vcId!); + await liveCareModel.getAlternativeServices(patient.vcId!); GifLoaderDialogUtils.hideDialog(context); if (liveCareModel.state == ViewState.ErrorLocal) { DrAppToastMsg.showErrorToast(liveCareModel.error); } else { - Navigator.of(context).pop(); - Navigator.of(context).pop(); + showAlternativesDialog(context, liveCareModel, (bool isConfirmed) async { + GifLoaderDialogUtils.showMyDialog(context); + await liveCareModel.endCallWithCharge(patient.vcId, isConfirmed); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } else { + DrAppToastMsg.showSuccesToast("You successfully completed call with charge"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } + }); } }); }, isDartIcon: true, dartIcon: DoctorApp.end_consultaion), PatientProfileCardModel(TranslationBase.of(context).sendLC!, TranslationBase.of(context).instruction!, "", 'patient/health_summary.png', - onTap: () {}, + onTap: () { + Helpers.showConfirmationDialog(context, + "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).sendLC} ${TranslationBase.of(context).instruction} ?", + () async { + Navigator.of(context).pop(); + GifLoaderDialogUtils.showMyDialog(context); + await liveCareModel.sendSMSInstruction(patient.vcId); + GifLoaderDialogUtils.hideDialog(context); + if (liveCareModel.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(liveCareModel.error); + } else { + DrAppToastMsg.showSuccesToast("You successfully sent SMS instructions"); + } + }); + }, isInPatient: isInpatient, isDartIcon: true, - isDisable: true, + // isDisable: true, dartIcon: DoctorApp.send_instruction), PatientProfileCardModel( TranslationBase.of(context).transferTo!, TranslationBase.of(context).admin!, '', 'patient/health_summary.png', onTap: () { Navigator.push(context, - MaterialPageRoute(builder: (BuildContext context) => LivaCareTransferToAdmin(patient: widget.patient))); + MaterialPageRoute(builder: (BuildContext context) => LivaCareTransferToAdmin(patient: patient))); }, isInPatient: isInpatient, isDartIcon: true, dartIcon: DoctorApp.transfer_to_admin), ]; @@ -135,17 +180,26 @@ class _EndCallScreenState extends State { }, builder: (_, model, w) => AppScaffold( baseViewModel: model, - appBarTitle: TranslationBase.of(context).patientProfile!, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBarTitle: TranslationBase + .of(context) + .patientProfile!, + backgroundColor: Theme + .of(context) + .scaffoldBackgroundColor, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(widget.patient, arrivalType ?? '7', '1', - isInpatient: isInpatient, - height: (widget.patient.patientStatusType != null && widget.patient.patientStatusType == 43) - ? 210 - : isDischargedPatient - ? 240 - : 0, - isDischargedPatient: isDischargedPatient), + appBar: PatientProfileAppBar(patientProfileAppBarModel :PatientProfileAppBarModel(patient: patient,isInpatient: isInpatient, + isDischargedPatient: isDischargedPatient, + height: (patient.patientStatusType != null && patient.patientStatusType == 43) + ? 210 + : isDischargedPatient + ? 240 + : 0, + ), + onPressed: (){ + Navigator.pop(context); + + }, + ), body: Container( height: !isSearchAndOut ? isDischargedPatient @@ -181,7 +235,7 @@ class _EndCallScreenState extends State { itemCount: cardsList.length, staggeredTileBuilder: (int index) => StaggeredTile.fit(1), itemBuilder: (BuildContext context, int index) => PatientProfileButton( - patient: widget.patient, + patient: patient, patientType: patientType, arrivalType: arrivalType, from: from, @@ -197,6 +251,7 @@ class _EndCallScreenState extends State { isLoading: cardsList[index].isLoading, isDartIcon: cardsList[index].isDartIcon, dartIcon: cardsList[index].dartIcon, + color: cardsList[index].color, ), ), ], @@ -247,4 +302,97 @@ class _EndCallScreenState extends State { ), ); } + + showAlternativesDialog(BuildContext context, LiveCarePatientViewModel model, + Function(bool) okFunction) { + return showDialog( + context: context, + barrierDismissible: false, // user must tap button! + builder: (_) { + return Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AlertDialog( + title: null, + content: Container( + height: MediaQuery.of(context).size.height / 2, + child: CheckBoxListWidget( + model: model, + ), + ), + actions: [ + AppButton( + onPressed: (){ + Navigator.of(context).pop(); + okFunction(true); + }, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + AppButton( + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + okFunction(false); + }, + title: TranslationBase.of(context).cancel, + fontColor: Colors.white, + color: Colors.red[600], + ), + ], + ), + ], + ), + ); + }); + } +} + +class CheckBoxListWidget extends StatefulWidget { + final LiveCarePatientViewModel model; + + const CheckBoxListWidget({ + Key key, + this.model, + }) : super(key: key); + + @override + _CheckBoxListState createState() => _CheckBoxListState(); +} + +class _CheckBoxListState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + ...widget.model.alternativeServicesList + .map( + (element) => Container( + child: CheckboxListTile( + title: AppText( + element.serviceName, + fontWeight: FontWeight.normal, + fontSize: SizeConfig.textMultiplier * 2.2, + ), + value: element.isSelected, + onChanged: (newValue) { + setState(() { + widget.model + .setSelectedCheckboxValues(element, newValue); + }); + }, + activeColor: Color(0xFFD02127), + controlAffinity: ListTileControlAffinity.leading, + contentPadding: EdgeInsets.all(0), + ), + ), + ) + .toList() + ], + ), + ); + } } diff --git a/lib/screens/live_care/live-care_transfer_to_admin.dart b/lib/screens/live_care/live-care_transfer_to_admin.dart index 89247b10..d30f996c 100644 --- a/lib/screens/live_care/live-care_transfer_to_admin.dart +++ b/lib/screens/live_care/live-care_transfer_to_admin.dart @@ -110,19 +110,20 @@ class _LivaCareTransferToAdminState extends State { if (noteController.text.isNotEmpty) { Helpers.showConfirmationDialog(context, "${TranslationBase.of(context).areYouSureYouWantTo} ${TranslationBase.of(context).transferTo}${TranslationBase.of(context).admin} ?", - () async { - Navigator.of(context).pop(); - GifLoaderDialogUtils.showMyDialog(context); - model.endCallWithCharge(widget.patient.vcId!); - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } else { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } - }); + () async { + Navigator.of(context).pop(); + GifLoaderDialogUtils.showMyDialog(context); + await model.transferToAdmin(widget.patient.vcId, noteController.text); + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast(model.error); + } else { + DrAppToastMsg.showSuccesToast("You successfully transfer to admin"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } + }); } }); }, diff --git a/lib/screens/live_care/live_care_patient_screen.dart b/lib/screens/live_care/live_care_patient_screen.dart index 11007718..f92ced53 100644 --- a/lib/screens/live_care/live_care_patient_screen.dart +++ b/lib/screens/live_care/live_care_patient_screen.dart @@ -6,7 +6,7 @@ import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart' import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; @@ -38,6 +38,7 @@ class _LiveCarePatientScreenState extends State { @override void dispose() { + _liveCareViewModel.isLogin(0); _liveCareViewModel = null!; timer?.cancel(); super.dispose(); @@ -49,6 +50,7 @@ class _LiveCarePatientScreenState extends State { onModelReady: (model) async { _liveCareViewModel = model; await model.getPendingPatientERForDoctorApp(); + await model.isLogin(1); }, builder: (_, model, w) => AppScaffold( baseViewModel: model, diff --git a/lib/screens/live_care/video_call.dart b/lib/screens/live_care/video_call.dart index aecccac7..10bab392 100644 --- a/lib/screens/live_care/video_call.dart +++ b/lib/screens/live_care/video_call.dart @@ -66,6 +66,7 @@ class _VideoCallPageState extends State { //'1_MX40NjgwMzIyNH5-MTU5MzY4MzYzODYwM35ucExWYVRVSm5Hcy9uWGZmM1lOa3czZHV-fg', kApiKey: '46209962', vcId: widget.patientData.vcId, + patientName: widget.patientData.fullName ?? widget.patientData.firstName != null ? "${widget.patientData.firstName} ${widget.patientData.lastName}" : "-", tokenID: token, //"hfkjshdf347r8743", generalId: "Cs2020@2016\$2958", doctorId: doctorprofile['DoctorID'], diff --git a/lib/screens/medical-file/health_summary_page.dart b/lib/screens/medical-file/health_summary_page.dart index 4a0020e1..e2af3da8 100644 --- a/lib/screens/medical-file/health_summary_page.dart +++ b/lib/screens/medical-file/health_summary_page.dart @@ -1,10 +1,10 @@ import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/medical-file/medical_file_details.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/doctor_card.dart'; @@ -28,10 +28,8 @@ class _HealthSummaryPageState extends State { return BaseView( onModelReady: (model) => model.getMedicalFile(mrn: patient.patientId), builder: (BuildContext context, MedicalFileViewModel model, Widget? child) => AppScaffold( - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patientType.toString() ?? "0", - arrivalType, + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/medical-file/medical_file_details.dart b/lib/screens/medical-file/medical_file_details.dart index a5f5b385..2ea90f0d 100644 --- a/lib/screens/medical-file/medical_file_details.dart +++ b/lib/screens/medical-file/medical_file_details.dart @@ -1,10 +1,10 @@ import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/expandable-widget-header-body.dart'; @@ -90,42 +90,68 @@ class _MedicalFileDetailsState extends State { bool isHistoryExpand = true; bool isAssessmentExpand = true; + PatientProfileAppBarModel patientProfileAppBarModel; + ProjectViewModel projectViewModel; + @override - Widget build(BuildContext context) { + void didChangeDependencies() { ProjectViewModel projectViewModel = Provider.of(context); + patientProfileAppBarModel = PatientProfileAppBarModel( + patient: patient, + doctorName: doctorName, + profileUrl: doctorImage, + clinic: clinicName, + isPrescriptions: true, + isMedicalFile: true, + episode: episode, + visitDate: + '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat( + vistDate, + ), isArabic: projectViewModel.isArabic)}', + isAppointmentHeader: true, + ); + + // TODO: implement didChangeDependencies + super.didChangeDependencies(); + } + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { return BaseView( onModelReady: (model) async { if (model.medicalFileList.length == 0) { model.getMedicalFile(mrn: pp); } }, - builder: (BuildContext context, MedicalFileViewModel model, Widget? child) => AppScaffold( - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: patient, - patientType: patient.patientType.toString() ?? "0", - arrivalType: patient.arrivedOn.toString()!, - doctorName: doctorName, - profileUrl: doctorImage, - clinic: clinicName, - isPrescriptions: true, - isMedicalFile: true, - episode: episode, - vistDate: '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat( - vistDate, - ), isArabic: projectViewModel.isArabic)}', - ), - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).medicalReport!.toUpperCase(), - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Center( - child: Container( - child: Column( - children: [ - model.medicalFileList.length != 0 && - model.medicalFileList[0].entityList![0].timelines![encounterNumber].timeLineEvents![0] - .consulations!.length != + builder: + (BuildContext context, MedicalFileViewModel model, Widget child) => + AppScaffold( + patientProfileAppBarModel: patientProfileAppBarModel, + isShowAppBar: true, + appBarTitle: TranslationBase + .of(context) + .medicalReport + .toUpperCase(), + body: NetworkBaseView( + baseViewModel: model, + child: SingleChildScrollView( + child: Center( + child: Container( + child: Column( + children: [ + model.medicalFileList.length != 0 && + model + .medicalFileList[0] + .entityList[0] + .timelines[encounterNumber] + .timeLineEvents[0] + .consulations + .length != 0 ? Padding( padding: EdgeInsets.all(10.0), diff --git a/lib/screens/patients/ECGPage.dart b/lib/screens/patients/ECGPage.dart index 1ea723fc..138559d4 100644 --- a/lib/screens/patients/ECGPage.dart +++ b/lib/screens/patients/ECGPage.dart @@ -3,10 +3,10 @@ import 'package:doctor_app_flutter/core/viewModel/PatientMuseViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -29,7 +29,8 @@ class ECGPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Color(0xffF8F8F8), - appBar: PatientProfileHeaderNewDesignAppBar(patient, arrivalType ?? '0', patientType), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:patient), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), diff --git a/lib/screens/patients/InPatientPage.dart b/lib/screens/patients/InPatientPage.dart index 0942c253..8a9d3cef 100644 --- a/lib/screens/patients/InPatientPage.dart +++ b/lib/screens/patients/InPatientPage.dart @@ -1,10 +1,12 @@ +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_container.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:flutter/material.dart'; @@ -60,7 +62,7 @@ class _InPatientPageState extends State { model.filterSearchResults(value); }), ), - model.filteredInPatientItems.length > 0 + model.state == ViewState.Idle?model.filteredInPatientItems.length > 0 ? Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 16.0), @@ -135,6 +137,13 @@ class _InPatientPageState extends State { child: SingleChildScrollView( child: Container(child: ErrorMessage(error: TranslationBase.of(context).noDataAvailable ?? "")), ), + ): Center( + child: Container( + height: 300, + width: 300, + child: Image.asset( + "assets/images/progress-loading-red.gif"), + ), ), ], ), diff --git a/lib/screens/patients/PatientsInPatientScreen.dart b/lib/screens/patients/PatientsInPatientScreen.dart index 927db334..88f85440 100644 --- a/lib/screens/patients/PatientsInPatientScreen.dart +++ b/lib/screens/patients/PatientsInPatientScreen.dart @@ -1,17 +1,27 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/models/dashboard/get_special_clinical_care_List_Respose_Model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'DischargedPatientPage.dart'; import 'InPatientPage.dart'; class PatientInPatientScreen extends StatefulWidget { + GetSpecialClinicalCareListResponseModel specialClinic; + + PatientInPatientScreen({Key key, this.specialClinic}); + @override _PatientInPatientScreenState createState() => _PatientInPatientScreenState(); } @@ -20,6 +30,9 @@ class _PatientInPatientScreenState extends State with Si late TabController _tabController; int _activeTab = 0; + int selectedMapId; + + @override void initState() { super.initState(); @@ -41,15 +54,26 @@ class _PatientInPatientScreenState extends State with Si @override Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; + final screenSize = MediaQuery + .of(context) + .size; PatientSearchRequestModel requestModel = PatientSearchRequestModel(); + ProjectViewModel projectsProvider = Provider.of(context); + return BaseView( onModelReady: (model) async { model.clearPatientList(); + // if (widget.specialClinic != null) { + // await model.getSpecialClinicalCareMappingList(widget.specialClinic.clinicID); + // requestModel.nursingStationID = + // model.specialClinicalCareMappingList[0].nursingStationID; + // requestModel.clinicID = 0; + // } model.getInPatientList(requestModel); }, - builder: (_, model, w) => AppScaffold( + builder: (_, model, w) => + AppScaffold( baseViewModel: model, isShowAppBar: false, body: Column( @@ -71,12 +95,125 @@ class _PatientInPatientScreenState extends State with Si ), Expanded( child: AppText( - TranslationBase.of(context).inPatient, + TranslationBase + .of(context) + .inPatient, fontSize: SizeConfig.textMultiplier * 2.8, fontWeight: FontWeight.bold, color: Color(0xFF2B353E), ), ), + if (model.specialClinicalCareMappingList.isNotEmpty && + widget.specialClinic != null && + _activeTab != 2) + Container( + width: MediaQuery.of(context).size.width * .3, + child: DropdownButtonHideUnderline( + child: DropdownButton( + dropdownColor: Colors.white, + iconEnabledColor: Colors.black, + isExpanded: true, + value: selectedMapId == null ? model + .specialClinicalCareMappingList[0] + .nursingStationID : selectedMapId, + iconSize: 25, + elevation: 16, + selectedItemBuilder: + (BuildContext context) { + return model + .specialClinicalCareMappingList + .map((item) { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment + .center, + children: [ + Container( + padding: + EdgeInsets.all(2), + margin: + EdgeInsets.all(2), + decoration: + new BoxDecoration( + color: + Colors.red[800], + borderRadius: + BorderRadius + .circular( + 20), + ), + constraints: + BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Center( + child: AppText( + model + .specialClinicalCareMappingList + .length + .toString(), + color: + Colors.white, + fontSize: + projectsProvider + .isArabic + ? 10 + : 11, + textAlign: + TextAlign + .center, + ), + )), + ], + ), + AppText(item.description, + fontSize: 12, + color: Colors.black, + fontWeight: + FontWeight.bold, + textAlign: TextAlign.end), + ], + ); + }).toList(); + }, + onChanged: (newValue) async { + setState(() { + selectedMapId = newValue; + }); + model.clearPatientList(); + GifLoaderDialogUtils.showMyDialog( + context); + + PatientSearchRequestModel requestModel = PatientSearchRequestModel( + nursingStationID: selectedMapId, clinicID: 0); + await model.getInPatientList(requestModel, isLocalBusy: true); + GifLoaderDialogUtils.hideDialog( + context); + if (model.state == + ViewState.ErrorLocal) { + DrAppToastMsg.showErrorToast( + model.error); + } + }, + items: model + .specialClinicalCareMappingList + .map((item) { + return DropdownMenuItem( + child: AppText( + item.description, + textAlign: TextAlign.left, + ), + value: item.nursingStationID, + ); + }).toList(), + )), + ) ]), ), ), diff --git a/lib/screens/patients/insurance_approval_screen_patient.dart b/lib/screens/patients/insurance_approval_screen_patient.dart index 172cf355..9090f24b 100644 --- a/lib/screens/patients/insurance_approval_screen_patient.dart +++ b/lib/screens/patients/insurance_approval_screen_patient.dart @@ -2,9 +2,9 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/InsuranceViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/patients/insurance_approvals_details.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/doctor_card_insurance.dart'; @@ -40,10 +40,8 @@ class _InsuranceApprovalScreenNewState extends State appointmentNo: patient?.appointmentNo, projectId: patient.projectId) : (model) => model.getInsuranceApproval(patient), builder: (BuildContext context, InsuranceViewModel model, Widget? child) => AppScaffold( - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patientType.toString() ?? "0", - patientType, + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient: isInpatient, ), isShowAppBar: true, diff --git a/lib/screens/patients/insurance_approvals_details.dart b/lib/screens/patients/insurance_approvals_details.dart index c47ca5dc..5275eff6 100644 --- a/lib/screens/patients/insurance_approvals_details.dart +++ b/lib/screens/patients/insurance_approvals_details.dart @@ -2,10 +2,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/InsuranceViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -44,599 +44,772 @@ class _InsuranceApprovalsDetailsState extends State { appointmentNo: patient.appointmentNo, projectId: patient.projectId) : (model) => model.getInsuranceApproval(patient) : null, - builder: (BuildContext context, InsuranceViewModel model, Widget? child) => AppScaffold( - isShowAppBar: true, - baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patient.patientType.toString(), patient.arrivedOn ?? ""), - body: patient.admissionNo != null - ? SingleChildScrollView( - child: Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Row( + builder: (BuildContext context, InsuranceViewModel model, Widget child) => + AppScaffold( + isShowAppBar: true, + baseViewModel: model, + patientProfileAppBarModel: + PatientProfileAppBarModel(patient: patient), + body: patient.admissionNo != null + ? SingleChildScrollView( + child: Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( children: [ - AppText( - TranslationBase.of(context).insurance22, - fontSize: 15.0, - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', + Row( + children: [ + AppText( + TranslationBase.of(context).insurance22, + fontSize: 15.0, + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + ), + ], ), - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).approvals22, - fontSize: 30.0, - fontWeight: FontWeight.w700, + Row( + children: [ + AppText( + TranslationBase.of(context).approvals22, + fontSize: 30.0, + fontWeight: FontWeight.w700, + ), + ], ), ], ), - ], - ), - ), - Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - border: Border.all( - width: 0.5, - color: Colors.white, - ), - borderRadius: BorderRadius.all( - Radius.circular(15.0), - ), - color: Colors.white), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Row( + ), + Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border.all( + width: 0.5, + color: Colors.white, + ), + borderRadius: BorderRadius.all( + Radius.circular(15.0), + ), + color: Colors.white), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( children: [ - AppText( - model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption != null - ? model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption ?? - "" - : "", - color: model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption != - null - ? "${model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption}" == - "Approved" || - "${model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption}" == - "تمت الموافقة" - ? Color(0xff359846) - : Color(0xffD02127) - : Color(0xffD02127), + Row( + children: [ + AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + .approvalStatusDescption != + null + ? model + .insuranceApprovalInPatient[ + indexInsurance] + .approvalStatusDescption ?? + "" + : "", + color: model + .insuranceApprovalInPatient[ + indexInsurance] + .approvalStatusDescption != + null + ? "${model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption}" == + "Approved" || + "${model.insuranceApprovalInPatient[indexInsurance].approvalStatusDescption}" == + "تمت الموافقة" + ? Color(0xff359846) + : Color(0xffD02127) + : Color(0xffD02127), + ), + ], ), - ], - ), - Row( - children: [ - AppText( - model.insuranceApprovalInPatient[indexInsurance].doctorName!.toUpperCase(), - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ) - ], - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - children: [ - Column( + Row( + children: [ + AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + .doctorName + .toUpperCase(), + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ) + ], + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( children: [ - Container( - height: 85.0, - width: 85.0, - child: CircleAvatar( - radius: SizeConfig.imageSizeMultiplier * 12, - // radius: (52) - child: ClipRRect( - borderRadius: BorderRadius.circular(50), - child: Image.network( - model.insuranceApprovalInPatient[indexInsurance].doctorImage ?? "", - fit: BoxFit.fill, - width: 700, + Column( + children: [ + Container( + height: 85.0, + width: 85.0, + child: CircleAvatar( + radius: SizeConfig + .imageSizeMultiplier * + 12, + // radius: (52) + child: ClipRRect( + borderRadius: + BorderRadius.circular( + 50), + child: Image.network( + model + .insuranceApprovalInPatient[ + indexInsurance] + .doctorImage, + fit: BoxFit.fill, + width: 700, + ), + ), + backgroundColor: + Colors.transparent, ), ), - backgroundColor: Colors.transparent, - ), + ], ), - ], - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - //mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 25.0, - ), - Row( + Expanded( + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + //mainAxisAlignment: MainAxisAlignment.center, children: [ - AppText( - TranslationBase.of(context).clinic! + ": ", - color: Colors.grey[500], - fontSize: 14, - ), - Expanded( - child: AppText( - model.insuranceApprovalInPatient[indexInsurance].clinicName, - fontSize: 14, - ), - ) - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).approvalNo! + ": ", - color: Colors.grey[500], - fontSize: 14, + SizedBox( + height: 25.0, ), - AppText( - model.insuranceApprovalInPatient[indexInsurance].approvalNo - .toString(), - fontSize: 14, - ) - ], - ), - Row( - children: [ - AppText( - 'Unused Count:', - color: Colors.grey[500], - fontSize: 14, + Row( + children: [ + AppText( + TranslationBase.of( + context) + .clinic + + ": ", + color: Colors.grey[500], + fontSize: 14, + ), + Expanded( + child: AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + .clinicName, + fontSize: 14, + ), + ) + ], ), - AppText( - model.insuranceApprovalInPatient[indexInsurance].unUsedCount - .toString(), - fontSize: 14, - ) - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).companyName! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + TranslationBase.of( + context) + .approvalNo + + ": ", + color: Colors.grey[500], + fontSize: 14, + ), + AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + .approvalNo + .toString(), + fontSize: 14, + ) + ], ), - AppText('Sample') - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).receiptOn! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + 'Unused Count:', + color: Colors.grey[500], + fontSize: 14, + ), + AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + .unUsedCount + .toString(), + fontSize: 14, + ) + ], ), - Expanded( - child: AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApprovalInPatient[indexInsurance].receiptOn ?? ""), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, - ), + Row( + children: [ + AppText( + TranslationBase.of( + context) + .companyName + + ": ", + color: Colors.grey[500], + ), + AppText('Sample') + ], ), - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).expiryDate! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + TranslationBase.of( + context) + .receiptOn + + ": ", + color: Colors.grey[500], + ), + Expanded( + child: AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApprovalInPatient[indexInsurance].receiptOn), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: + FontWeight.w600, + ), + ), + ], ), - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApprovalInPatient[indexInsurance].expiryDate ?? ""), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, + Row( + children: [ + AppText( + TranslationBase.of( + context) + .expiryDate + + ": ", + color: Colors.grey[500], + ), + AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApprovalInPatient[indexInsurance].expiryDate), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: + FontWeight.w600, + ), + ], ), ], ), - ], + ), ), - ), + ], ), - ], - ), - ), - SizedBox( - height: 20.0, - ), - Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - children: [ - Expanded( - child: AppText( - TranslationBase.of(context).procedure, - fontWeight: FontWeight.w700, - ), - ), - Expanded( - child: AppText( - TranslationBase.of(context).status, - fontWeight: FontWeight.w700, - ), + ), + SizedBox( + height: 20.0, + ), + Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( + children: [ + Expanded( + child: AppText( + TranslationBase.of(context) + .procedure, + fontWeight: FontWeight.w700, + ), + ), + Expanded( + child: AppText( + TranslationBase.of(context) + .status, + fontWeight: FontWeight.w700, + ), + ), + Expanded( + child: AppText( + TranslationBase.of(context) + .usageStatus, + fontWeight: FontWeight.w700, + ), + ) + ], ), - Expanded( - child: AppText( - TranslationBase.of(context).usageStatus, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - ), - Divider( - color: Colors.black, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: ListView.builder( - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: model - .insuranceApprovalInPatient[indexInsurance].apporvalDetails!.length, - itemBuilder: (BuildContext context, int index) { - return Container( - child: Column( - children: [ - Row( + ), + Divider( + color: Colors.black, + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: ListView.builder( + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: model + .insuranceApprovalInPatient[ + indexInsurance] + .apporvalDetails + .length, + itemBuilder: + (BuildContext context, + int index) { + return Container( + child: Column( children: [ - Expanded( - child: Container( - child: AppText( - model.insuranceApprovalInPatient[indexInsurance] - ?.apporvalDetails![index]?.procedureName ?? - "", - textAlign: TextAlign.start, + Row( + children: [ + Expanded( + child: Container( + child: AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.procedureName ?? + "", + textAlign: + TextAlign + .start, + ), + ), ), - ), - ), - Expanded( - child: Container( - child: AppText( - model.insuranceApprovalInPatient[indexInsurance] - ?.apporvalDetails![index]?.status ?? - "", - textAlign: TextAlign.center, + Expanded( + child: Container( + child: AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.status ?? + "", + textAlign: + TextAlign + .center, + ), + ), ), - ), - ), - Expanded( - child: Container( - child: AppText( - model.insuranceApprovalInPatient[indexInsurance] - ?.apporvalDetails![index]?.isInvoicedDesc ?? - "", - textAlign: TextAlign.center, + Expanded( + child: Container( + child: AppText( + model + .insuranceApprovalInPatient[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.isInvoicedDesc ?? + "", + textAlign: + TextAlign + .center, + ), + ), ), - ), + ], + ), + SizedBox( + width: 5, + ), + Divider( + color: Colors.black38, ), ], ), - SizedBox( - width: 5, - ), - Divider( - color: Colors.black38, - ), - ], - ), - ); - }), + ); + }), + ), + ], ), - ], - ), + ), + ], ), - ], + ), ), - ), + ], ), - ], - ), - ), - ) - : SingleChildScrollView( - child: Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Row( + ), + ) + : SingleChildScrollView( + child: Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( children: [ - AppText( - TranslationBase.of(context).insurance22, - fontSize: 15.0, - fontWeight: FontWeight.w600, - fontFamily: 'Poppins', + Row( + children: [ + AppText( + TranslationBase.of(context).insurance22, + fontSize: 15.0, + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + ), + ], ), - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).approvals22, - fontSize: 30.0, - fontWeight: FontWeight.w700, + Row( + children: [ + AppText( + TranslationBase.of(context).approvals22, + fontSize: 30.0, + fontWeight: FontWeight.w700, + ), + ], ), ], ), - ], - ), - ), - Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - border: Border.all( - width: 0.5, - color: Colors.white, - ), - borderRadius: BorderRadius.all( - Radius.circular(15.0), - ), - color: Colors.white), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Row( + ), + Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + border: Border.all( + width: 0.5, + color: Colors.white, + ), + borderRadius: BorderRadius.all( + Radius.circular(15.0), + ), + color: Colors.white), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( children: [ - AppText( - model.insuranceApproval[indexInsurance].approvalStatusDescption != null - ? model.insuranceApproval[indexInsurance].approvalStatusDescption ?? "" - : "", - color: model.insuranceApproval[indexInsurance].approvalStatusDescption != null - ? "${model.insuranceApproval[indexInsurance].approvalStatusDescption}" == - "Approved" - ? Color(0xff359846) - : Color(0xffD02127) - : Color(0xffD02127), + Row( + children: [ + AppText( + model + .insuranceApproval[ + indexInsurance] + .approvalStatusDescption != + null + ? model + .insuranceApproval[ + indexInsurance] + .approvalStatusDescption ?? + "" + : "", + color: model + .insuranceApproval[ + indexInsurance] + .approvalStatusDescption != + null + ? "${model.insuranceApproval[indexInsurance].approvalStatusDescption}" == + "Approved" + ? Color(0xff359846) + : Color(0xffD02127) + : Color(0xffD02127), + ), + ], ), - ], - ), - Row( - children: [ - AppText( - model.insuranceApproval[indexInsurance].doctorName!.toUpperCase(), - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ) - ], - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - children: [ - Column( + Row( + children: [ + AppText( + model + .insuranceApproval[indexInsurance] + .doctorName + .toUpperCase(), + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ) + ], + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( children: [ - Container( - height: 85.0, - width: 85.0, - child: CircleAvatar( - radius: SizeConfig.imageSizeMultiplier * 12, - // radius: (52) - child: ClipRRect( - borderRadius: BorderRadius.circular(50), - child: Image.network( - model.insuranceApproval[indexInsurance].doctorImage ?? "", - fit: BoxFit.fill, - width: 700, + Column( + children: [ + Container( + height: 85.0, + width: 85.0, + child: CircleAvatar( + radius: SizeConfig + .imageSizeMultiplier * + 12, + // radius: (52) + child: ClipRRect( + borderRadius: + BorderRadius.circular( + 50), + child: Image.network( + model + .insuranceApproval[ + indexInsurance] + .doctorImage, + fit: BoxFit.fill, + width: 700, + ), + ), + backgroundColor: + Colors.transparent, ), ), - backgroundColor: Colors.transparent, - ), + ], ), - ], - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - //mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 25.0, - ), - Row( + Expanded( + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + //mainAxisAlignment: MainAxisAlignment.center, children: [ - AppText( - TranslationBase.of(context).clinic! + ": ", - color: Colors.grey[500], - fontSize: 14, + SizedBox( + height: 25.0, ), - Expanded( - child: AppText( - model.insuranceApproval[indexInsurance].clinicName, - fontSize: 14, - ), - ) - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).approvalNo! + ": ", - color: Colors.grey[500], - fontSize: 14, + Row( + children: [ + AppText( + TranslationBase.of( + context) + .clinic + + ": ", + color: Colors.grey[500], + fontSize: 14, + ), + Expanded( + child: AppText( + model + .insuranceApproval[ + indexInsurance] + .clinicName, + fontSize: 14, + ), + ) + ], ), - AppText( - model.insuranceApproval[indexInsurance].approvalNo.toString(), - fontSize: 14, - ) - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).unusedCount! + ": ", - color: Colors.grey[500], - fontSize: 14, + Row( + children: [ + AppText( + TranslationBase.of( + context) + .approvalNo + + ": ", + color: Colors.grey[500], + fontSize: 14, + ), + AppText( + model + .insuranceApproval[ + indexInsurance] + .approvalNo + .toString(), + fontSize: 14, + ) + ], ), - AppText( - model.insuranceApproval[indexInsurance].unUsedCount.toString(), - fontSize: 14, - ) - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).companyName! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + TranslationBase.of( + context) + .unusedCount + + ": ", + color: Colors.grey[500], + fontSize: 14, + ), + AppText( + model + .insuranceApproval[ + indexInsurance] + .unUsedCount + .toString(), + fontSize: 14, + ) + ], ), - AppText('Sample') - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).receiptOn! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + TranslationBase.of( + context) + .companyName + + ": ", + color: Colors.grey[500], + ), + AppText('Sample') + ], ), - Expanded( - child: AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApproval[indexInsurance].rceiptOn ?? ""), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, - ), + Row( + children: [ + AppText( + TranslationBase.of( + context) + .receiptOn + + ": ", + color: Colors.grey[500], + ), + Expanded( + child: AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApproval[indexInsurance].rceiptOn), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: + FontWeight.w600, + ), + ), + ], ), - ], - ), - Row( - children: [ - AppText( - TranslationBase.of(context).expiryDate! + ": ", - color: Colors.grey[500], + Row( + children: [ + AppText( + TranslationBase.of( + context) + .expiryDate + + ": ", + color: Colors.grey[500], + ), + if (model + .insuranceApproval[ + indexInsurance] + .expiryDate != + null) + AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApproval[indexInsurance].expiryDate), isArabic: projectViewModel.isArabic)}', + color: Colors.black, + fontWeight: + FontWeight.w600, + ), + ], ), - if (model.insuranceApproval[indexInsurance].expiryDate != null) - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(AppDateUtils.getDateTimeFromServerFormat(model.insuranceApproval[indexInsurance].expiryDate ?? ""), isArabic: projectViewModel.isArabic)}', - color: Colors.black, - fontWeight: FontWeight.w600, - ), ], ), - ], + ), ), - ), + ], ), - ], - ), - ), - SizedBox( - height: 20.0, - ), - Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - children: [ - Expanded( - child: AppText( - TranslationBase.of(context).procedure, - fontWeight: FontWeight.w700, - ), - ), - Expanded( - child: AppText( - TranslationBase.of(context).status, - fontWeight: FontWeight.w700, - ), + ), + SizedBox( + height: 20.0, + ), + Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Row( + children: [ + Expanded( + child: AppText( + TranslationBase.of(context) + .procedure, + fontWeight: FontWeight.w700, + ), + ), + Expanded( + child: AppText( + TranslationBase.of(context) + .status, + fontWeight: FontWeight.w700, + ), + ), + Expanded( + child: AppText( + TranslationBase.of(context) + .usageStatus, + fontWeight: FontWeight.w700, + ), + ) + ], ), - Expanded( - child: AppText( - TranslationBase.of(context).usageStatus, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - ), - Divider( - color: Colors.black, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: ListView.builder( - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: model.insuranceApproval[indexInsurance].apporvalDetails!.length, - itemBuilder: (BuildContext context, int index) { - return Container( - child: Column( - children: [ - Row( + ), + Divider( + color: Colors.black, + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: ListView.builder( + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: model + .insuranceApproval[ + indexInsurance] + .apporvalDetails + .length, + itemBuilder: + (BuildContext context, + int index) { + return Container( + child: Column( children: [ - Expanded( - child: Container( - child: AppText( - model.insuranceApproval[indexInsurance] - ?.apporvalDetails![index]?.procedureName ?? - "", - textAlign: TextAlign.start, + Row( + children: [ + Expanded( + child: Container( + child: AppText( + model + .insuranceApproval[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.procedureName ?? + "", + textAlign: + TextAlign + .start, + ), + ), ), - ), - ), - Expanded( - child: Container( - child: AppText( - model.insuranceApproval[indexInsurance] - ?.apporvalDetails![index]?.status ?? - "", - textAlign: TextAlign.center, + Expanded( + child: Container( + child: AppText( + model + .insuranceApproval[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.status ?? + "", + textAlign: + TextAlign + .center, + ), + ), ), - ), - ), - Expanded( - child: Container( - child: AppText( - model.insuranceApproval[indexInsurance] - ?.apporvalDetails![index]?.isInvoicedDesc ?? - "", - textAlign: TextAlign.center, + Expanded( + child: Container( + child: AppText( + model + .insuranceApproval[ + indexInsurance] + ?.apporvalDetails[ + index] + ?.isInvoicedDesc ?? + "", + textAlign: + TextAlign + .center, + ), + ), ), - ), + ], + ), + SizedBox( + width: 5, + ), + Divider( + color: Colors.black38, ), ], ), - SizedBox( - width: 5, - ), - Divider( - color: Colors.black38, - ), - ], - ), - ); - }), + ); + }), + ), + ], ), - ], - ), + ), + ], ), - ], + ), ), - ), + ], ), - ], - ), - ), - )), + ), + )), ); } } diff --git a/lib/screens/patients/out_patient/out_patient_screen.dart b/lib/screens/patients/out_patient/out_patient_screen.dart index ad4c3fbf..d97678a3 100644 --- a/lib/screens/patients/out_patient/out_patient_screen.dart +++ b/lib/screens/patients/out_patient/out_patient_screen.dart @@ -1,10 +1,8 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/filter_type.dart'; import 'package:doctor_app_flutter/core/enum/patient_type.dart'; - import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; - import 'package:doctor_app_flutter/core/viewModel/PatientSearchViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -14,7 +12,7 @@ import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; diff --git a/lib/screens/patients/patient_search/patient_search_result_screen.dart b/lib/screens/patients/patient_search/patient_search_result_screen.dart index ac28e26b..39b619c0 100644 --- a/lib/screens/patients/patient_search/patient_search_result_screen.dart +++ b/lib/screens/patients/patient_search/patient_search_result_screen.dart @@ -10,13 +10,11 @@ import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/PatientCard.dart'; +import 'package:doctor_app_flutter/widgets/patients/patient_card/PatientCard.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app_text_form_field.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; diff --git a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart index be718c56..78529f16 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-detail-screen.dart @@ -7,12 +7,12 @@ import 'package:doctor_app_flutter/models/SOAP/GetAssessmentResModel.dart'; import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart'; import 'package:doctor_app_flutter/models/SOAP/order-procedure.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -47,7 +47,9 @@ class _UcafDetailScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + + + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), appBarTitle: TranslationBase.of(context).ucaf ?? "", body: Column( children: [ diff --git a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart index 40024b6d..63faca8e 100644 --- a/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart +++ b/lib/screens/patients/profile/UCAF/UCAF-input-screen.dart @@ -1,13 +1,12 @@ -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-ucaf-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -65,7 +64,7 @@ class _UCAFInputScreenState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), appBarTitle: TranslationBase.of(context).ucaf ?? "", body: model.patientVitalSignsHistory.length > 0 && model.patientChiefComplaintList != null && diff --git a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart index ab22cb6b..82b9bc1c 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-first-screen.dart @@ -4,10 +4,10 @@ import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -59,7 +59,7 @@ class _AdmissionRequestThirdScreenState extends State AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), appBarTitle: TranslationBase.of(context).admissionRequest!, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart index 547fa5cb..9766e3fd 100644 --- a/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request-third-screen.dart @@ -5,10 +5,10 @@ import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -50,7 +50,8 @@ class _AdmissionRequestThirdScreenState extends State AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), + appBarTitle: TranslationBase.of(context).admissionRequest!, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart index 0c9ccb4e..0ffc188c 100644 --- a/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart +++ b/lib/screens/patients/profile/admission-request/admission-request_second-screen.dart @@ -6,11 +6,11 @@ import 'package:doctor_app_flutter/core/model/admissionRequest/admission-request import 'package:doctor_app_flutter/core/viewModel/patient-admission-request-viewmodel.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -72,7 +72,7 @@ class _AdmissionRequestSecondScreenState extends State AppScaffold( baseViewModel: model, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), appBarTitle: TranslationBase.of(context).admissionRequest!, body: GestureDetector( onTap: () { diff --git a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart index 7f581945..2f5f6e69 100644 --- a/lib/screens/patients/profile/lab_result/laboratory_result_page.dart +++ b/lib/screens/patients/profile/lab_result/laboratory_result_page.dart @@ -1,8 +1,8 @@ import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart'; import 'package:doctor_app_flutter/core/viewModel/labs_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -32,29 +32,15 @@ class _LaboratoryResultPageState extends State { @override Widget build(BuildContext context) { return BaseView( - // onModelReady: (model) => model.getLaboratoryResult( - // invoiceNo: widget.patientLabOrders.invoiceNo, - // clinicID: widget.patientLabOrders.clinicID, - // projectID: widget.patientLabOrders.projectID, - // orderNo: widget.patientLabOrders.orderNo, - // patient: widget.patient, - // isInpatient: widget.patientType == "1"), onModelReady: (model) => model.getPatientLabResult( patientLabOrder: widget.patientLabOrders, patient: widget.patient, isInpatient: true), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBar: PatientProfileHeaderWhitAppointmentAppBar( - patient: widget.patient, - patientType: widget.patientType ?? "0", - arrivalType: widget.arrivalType ?? "0", - orderNo: widget.patientLabOrders.orderNo, - appointmentDate: widget.patientLabOrders.orderDate, - doctorName: widget.patientLabOrders.doctorName, - branch: widget.patientLabOrders.projectName, - clinic: widget.patientLabOrders.clinicDescription, - profileUrl: widget.patientLabOrders.doctorImageURL, - invoiceNO: widget.patientLabOrders.invoiceNo, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:widget.patient,isInpatient:widget.isInpatient, + isFromLabResult: true, + appointmentDate: widget.patientLabOrders.orderDate,), + baseViewModel: model, body: AppScaffold( isShowAppBar: false, diff --git a/lib/screens/patients/profile/lab_result/labs_home_page.dart b/lib/screens/patients/profile/lab_result/labs_home_page.dart index a43ed52e..8d233825 100644 --- a/lib/screens/patients/profile/lab_result/labs_home_page.dart +++ b/lib/screens/patients/profile/lab_result/labs_home_page.dart @@ -1,13 +1,13 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/lab_result/laboratory_result_page.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_lab_home_screen.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_lab_orders.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; +import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/doctor_card.dart'; @@ -51,12 +51,8 @@ class _LabsHomePageState extends State { baseViewModel: model, backgroundColor: Colors.grey[100]!, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patient.patientType.toString() ?? '0', - patientType, - isInpatient: isInpatient, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient:isInpatient,), body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: FractionallySizedBox( @@ -114,10 +110,12 @@ class _LabsHomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddLabHomeScreen( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.LAB_RESULT, + ), + ), ); }, label: TranslationBase.of(context).applyForNewLabOrder ?? "", diff --git a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart index 428ddf4a..06ca9256 100644 --- a/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart +++ b/lib/screens/patients/profile/medical_report/AddVerifyMedicalReport.dart @@ -6,6 +6,7 @@ import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_loader_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; @@ -39,24 +40,35 @@ class _AddVerifyMedicalReportState extends State { ? TranslationBase.of(context).medicalReportAdd! : TranslationBase.of(context).medicalReportVerify!, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: Column( - children: [ - Expanded( - child: Container( - margin: EdgeInsets.all(16), - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + body: model.state == ViewState.BusyLocal + ? AppLoaderWidget() + : Column( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.all(16), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (model.medicalReportTemplate.length > 0) + // if (model.medicalReportTemplate.length > 0) HtmlRichEditor( - initialText: model.medicalReportTemplate[0].templateTextHtml!, - height: MediaQuery.of(context).size.height * 0.75, - controller: _controller, + initialText: (medicalReport != null + ? medicalReport.reportDataHtml + : model.medicalReportTemplate + .length > 0 ? model + .medicalReportTemplate[0] : ""), + hint: "Write the medical report ", + height: + MediaQuery + .of(context) + .size + .height * + 0.75, ), ], ), diff --git a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart index 1225eba4..ceac8526 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportDetailPage.dart @@ -1,16 +1,13 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel.dart'; -import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/MedicalReport/MeidcalReportModel.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; @@ -31,11 +28,8 @@ class MedicalReportDetailPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patientType, - arrivalType, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:patient), body: Container( child: SingleChildScrollView( child: Column( diff --git a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart index 1babfab2..0d40f0a3 100644 --- a/lib/screens/patients/profile/medical_report/MedicalReportPage.dart +++ b/lib/screens/patients/profile/medical_report/MedicalReportPage.dart @@ -4,20 +4,20 @@ import 'package:doctor_app_flutter/core/viewModel/PatientMedicalReportViewModel. import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/large_avatar.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_html/flutter_html.dart'; import 'package:provider/provider.dart'; import '../../../../routes.dart'; @@ -43,11 +43,8 @@ class MedicalReportPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patientType, - arrivalType, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:patient), body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( @@ -75,12 +72,15 @@ class MedicalReportPage extends StatelessWidget { ), AddNewOrder( onTap: () { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + if (model.hasOnHold()) { + Helpers.showErrorToast( + "Please Verified the on hold report to be able to add new one"); + } else {Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, 'type': MedicalReportStatus.ADD - }); + });} }, label: TranslationBase.of(context).createNewMedicalReport!, ), @@ -90,14 +90,14 @@ class MedicalReportPage extends StatelessWidget { (index) => InkWell( onTap: () { if (model.medicalReportList[index].status == 1) { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { + Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, 'medicalReport': model.medicalReportList[index] }); } else { - Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_INSERT, arguments: { + Navigator.of(context).pushNamed(PATIENT_MEDICAL_REPORT_DETAIL, arguments: { 'patient': patient, 'patientType': patientType, 'arrivalType': arrivalType, @@ -110,7 +110,9 @@ class MedicalReportPage extends StatelessWidget { margin: EdgeInsets.symmetric(horizontal: 8), child: CardWithBgWidget( hasBorder: false, - bgColor: model.medicalReportList[index].status == 1 ? Colors.red[700]! : Colors.green[700]!, + bgColor: model.medicalReportList[index].status == 1 + ? Color(0xFFCC9B14) + : Colors.green[700], widget: Column( children: [ Row( @@ -124,7 +126,7 @@ class MedicalReportPage extends StatelessWidget { ? TranslationBase.of(context).onHold : TranslationBase.of(context).verified, color: model.medicalReportList[index].status == 1 - ? Colors.red[700] + ? Color(0xFFCC9B14) : Colors.green[700], fontSize: 1.4 * SizeConfig.textMultiplier, bold: true, @@ -201,7 +203,8 @@ class MedicalReportPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ Icon( - model.medicalReportList[index].status == 1 ? EvaIcons.eye : DoctorApp.edit_1, + model.medicalReportList[index].status == 1 ? DoctorApp.edit_1 + :EvaIcons.eye , ), ], ), diff --git a/lib/screens/patients/profile/note/progress_note_screen.dart b/lib/screens/patients/profile/note/progress_note_screen.dart index 5f5356f0..8e47ba60 100644 --- a/lib/screens/patients/profile/note/progress_note_screen.dart +++ b/lib/screens/patients/profile/note/progress_note_screen.dart @@ -4,13 +4,13 @@ import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/models/patient/progress_note_request.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/note/update_note.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/divider_with_spaces_around.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/dr_app_embedded_error.dart'; @@ -76,11 +76,9 @@ class _ProgressNoteState extends State { builder: (_, model, w) => AppScaffold( baseViewModel: model, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - // appBarTitle: TranslationBase.of(context).progressNote, - appBar: PatientProfileHeaderNewDesignAppBar( + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, - patient.patientType.toString() ?? '0', - arrivalType, isInpatient: true, ), body: model.patientProgressNoteList == null || model.patientProgressNoteList.length == 0 diff --git a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart index c11f9ffc..39148cf9 100644 --- a/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart +++ b/lib/screens/patients/profile/profile_screen/PatientProfileCardModel.dart @@ -13,6 +13,7 @@ class PatientProfileCardModel { final bool isSelectInpatient; final bool isDartIcon; final IconData? dartIcon; + final Color color; PatientProfileCardModel(this.nameLine1, this.nameLine2, this.route, this.icon, {this.isInPatient = false, @@ -22,5 +23,7 @@ class PatientProfileCardModel { this.isDischargedPatient = false, this.isSelectInpatient = false, this.isDartIcon = false, - this.dartIcon}); + this.dartIcon, + this.color, + }); } diff --git a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart index ef65c1b0..228d87ae 100644 --- a/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart +++ b/lib/screens/patients/profile/profile_screen/patient_profile_screen.dart @@ -1,26 +1,34 @@ +import 'dart:async'; + import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/service/VideoCallService.dart'; import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart'; import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_InPatient.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_other.dart'; import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/profile_gird_for_search.dart'; +import 'package:doctor_app_flutter/util/NotificationPermissionUtils.dart'; import 'package:doctor_app_flutter/util/VideoChannel.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; +import 'package:quiver/async.dart'; +import '../../../../locator.dart'; import '../../../../routes.dart'; class PatientProfileScreen extends StatefulWidget { @@ -45,10 +53,15 @@ class _PatientProfileScreenState extends State with Single late TabController _tabController; int index = 0; int _activeTab = 0; + + StreamController videoCallDurationStreamController; + Stream videoCallDurationStream = (() async*{})(); @override void initState() { _tabController = TabController(length: 2, vsync: this); super.initState(); + videoCallDurationStreamController = StreamController(); + videoCallDurationStream = videoCallDurationStreamController.stream; } @override @@ -81,12 +94,32 @@ class _PatientProfileScreenState extends State with Single if (routeArgs.containsKey("isFromLiveCare")) { isFromLiveCare = routeArgs['isFromLiveCare']; } + if(routeArgs.containsKey("isCallFinished")) { + isCallFinished = routeArgs['isCallFinished']; + } if (isInpatient) _activeTab = 0; else _activeTab = 1; } + StreamSubscription callTimer; + callConnected(){ + callTimer = CountdownTimer(Duration(minutes: 90), Duration(seconds: 1)).listen(null) + ..onDone(() { + callTimer.cancel(); + }) + ..onData((data) { + var t = Helpers.timeFrom(duration: data.elapsed); + videoCallDurationStreamController.sink.add(t); + }); + } + + callDisconnected(){ + callTimer.cancel(); + videoCallDurationStreamController.sink.add(null); + } + @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; @@ -102,7 +135,7 @@ class _PatientProfileScreenState extends State with Single Column( children: [ PatientProfileHeaderNewDesignAppBar(patient, arrivalType ?? '0', patientType, - isInpatient: isInpatient, + videoCallDurationStream: videoCallDurationStream,isInpatient: isInpatient, isFromLiveCare: isFromLiveCare, height: (patient.patientStatusType != null && patient.patientStatusType == 43) ? 210 @@ -157,7 +190,9 @@ class _PatientProfileScreenState extends State with Single ), ], ), - if (patient.patientStatusType != null && patient.patientStatusType == 43) + if (isFromLiveCare + ? patient.episodeNo != null + :patient.patientStatusType != null && patient.patientStatusType == 43) BaseView( onModelReady: (model) async {}, builder: (_, model, w) => Positioned( @@ -171,7 +206,9 @@ class _PatientProfileScreenState extends State with Single AppButton( title: "${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}", - color: patient.patientStatusType == 43 ? Colors.red.shade700 : Colors.grey.shade700, + color: isFromLiveCare + ? Colors.red.shade700 + :patient.patientStatusType == 43 ? Colors.red.shade700 : Colors.grey.shade700, fontColor: Colors.white, vPadding: 8, radius: 30, @@ -184,7 +221,9 @@ class _PatientProfileScreenState extends State with Single height: 30, ), onPressed: () async { - if (patient.patientStatusType == 43) { + if ((isFromLiveCare && + patient.appointmentNo != null && + patient.appointmentNo != 0) ||patient.patientStatusType == 43) { PostEpisodeReqModel postEpisodeReqModel = PostEpisodeReqModel( appointmentNo: patient.appointmentNo, patientMRN: patient.patientMRN); GifLoaderDialogUtils.showMyDialog(context); @@ -200,8 +239,9 @@ class _PatientProfileScreenState extends State with Single AppButton( title: "${TranslationBase.of(context).update}\n${TranslationBase.of(context).episode}", - color: - patient.patientStatusType == 43 ? Colors.red.shade700 : Colors.grey.shade700, + color:isFromLiveCare + ? Colors.red.shade700 + :patient.patientStatusType == 43 ? Colors.red.shade700 : Colors.grey.shade700, fontColor: Colors.white, vPadding: 8, radius: 30, @@ -214,7 +254,10 @@ class _PatientProfileScreenState extends State with Single height: 30, ), onPressed: () { - if (patient.patientStatusType == 43) { + if ((isFromLiveCare && + patient.appointmentNo != + null && + patient.appointmentNo != 0) ||patient.patientStatusType == 43) { Navigator.of(context) .pushNamed(UPDATE_EPISODE, arguments: {'patient': patient}); } @@ -254,7 +297,9 @@ class _PatientProfileScreenState extends State with Single : TranslationBase.of(context).initiateCall, disabled: model.state == ViewState.BusyLocal, onPressed: () async { - if (isCallFinished) { + // Navigator.push(context, MaterialPageRoute( + // builder: (BuildContext context) => + // EndCallScreen(patient:patient)));if (isCallFinished) { Navigator.push( context, MaterialPageRoute( @@ -271,71 +316,30 @@ class _PatientProfileScreenState extends State with Single patient.appointmentNo = model.startCallRes.appointmentNo; patient.episodeNo = 0; - GifLoaderDialogUtils.hideDialog(context); - await VideoChannel.openVideoCallScreen( - kToken: model.startCallRes.openTokenID, - kSessionId: model.startCallRes.openSessionID, - kApiKey: '46209962', - vcId: patient.vcId, - tokenID: await model.getToken(), - generalId: GENERAL_ID, - doctorId: model.doctorProfile!.doctorID, - onFailure: (String error) { - DrAppToastMsg.showErrorToast(error); - }, - onCallEnd: () { - WidgetsBinding.instance!.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model - .endCall( - patient.vcId!, - false, - ) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }, - onCallNotRespond: (SessionStatusModel sessionStatusModel) { - WidgetsBinding.instance!.addPostFrameCallback((_) { - GifLoaderDialogUtils.showMyDialog(context); - model - .endCall( - patient.vcId!, - sessionStatusModel.sessionStatus == 3, - ) - .then((value) { - GifLoaderDialogUtils.hideDialog(context); - if (model.state == ViewState.ErrorLocal) { - DrAppToastMsg.showErrorToast(model.error); - } - setState(() { - isCallFinished = true; - }); - }); - }); - }); - } - } - }, - ), - ), + GifLoaderDialogUtils.hideDialog(context); + AppPermissionsUtils.requestVideoCallPermission(context: context,onTapGrant: (){ + locator().openVideo(model.startCallRes, patient, callConnected, callDisconnected); + }); + + + } + } + + + }, ), ), - SizedBox( - height: 5, - ), - ], + ), ), - ) - : null, - ), + SizedBox( + height: 5, + ), + ], + ), + ) : null, + ), + + ); } } diff --git a/lib/screens/patients/profile/radiology/radiology_details_page.dart b/lib/screens/patients/profile/radiology/radiology_details_page.dart index 9bc0e8aa..db3d0bfd 100644 --- a/lib/screens/patients/profile/radiology/radiology_details_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_details_page.dart @@ -1,9 +1,9 @@ import 'package:doctor_app_flutter/core/model/radiology/final_radiology.dart'; import 'package:doctor_app_flutter/core/viewModel/radiology_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/secondary_button.dart'; @@ -16,9 +16,11 @@ class RadiologyDetailsPage extends StatelessWidget { final PatiantInformtion patient; final String? patientType; final String? arrivalType; + final bool isInpatient; RadiologyDetailsPage( - {Key? key, required this.finalRadiology, required this.patient, this.patientType, this.arrivalType}); + {Key? key, required this.finalRadiology, required this.patient, this.patientType, this.arrivalType, + this.isInpatient = false}); @override Widget build(BuildContext context) { @@ -29,16 +31,15 @@ class RadiologyDetailsPage extends StatelessWidget { lineItem: finalRadiology.invoiceLineItemNo, invoiceNo: finalRadiology.invoiceNo), builder: (_, model, widget) => AppScaffold( - appBar: PatientProfileHeaderWhitAppointmentAppBar( + patientProfileAppBarModel: PatientProfileAppBarModel( patient: patient, - patientType: patientType ?? "0", - arrivalType: arrivalType ?? "0", appointmentDate: finalRadiology.orderDate, doctorName: finalRadiology.doctorName, clinic: finalRadiology.clinicDescription, branch: finalRadiology.projectName, profileUrl: finalRadiology.doctorImageURL, invoiceNO: finalRadiology.invoiceNo.toString(), + isAppointmentHeader: true, ), isShowAppBar: true, baseViewModel: model, diff --git a/lib/screens/patients/profile/radiology/radiology_home_page.dart b/lib/screens/patients/profile/radiology/radiology_home_page.dart index a35721b8..22f96c09 100644 --- a/lib/screens/patients/profile/radiology/radiology_home_page.dart +++ b/lib/screens/patients/profile/radiology/radiology_home_page.dart @@ -1,13 +1,13 @@ import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/radiology/radiology_details_page.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_radiology_order.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_radiology_screen.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; +import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/doctor_card.dart'; @@ -49,12 +49,8 @@ class _RadiologyHomePageState extends State { isShowAppBar: true, backgroundColor: Colors.grey[100], // appBarTitle: TranslationBase.of(context).radiology, - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patient.patientType.toString() ?? '0', - arrivalType, - isInpatient: isInpatient, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient:isInpatient,), baseViewModel: model, body: FractionallySizedBox( widthFactor: 1.0, @@ -111,10 +107,12 @@ class _RadiologyHomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddRadiologyScreen( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.RADIOLOGY, + ), + ), ); }, label: TranslationBase.of(context).applyForRadiologyOrder ?? "", @@ -180,6 +178,7 @@ class _RadiologyHomePageState extends State { page: RadiologyDetailsPage( finalRadiology: model.radiologyList[index], patient: patient, + isInpatient:isInpatient ), ), ); diff --git a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart index e663dc64..2069f446 100644 --- a/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart +++ b/lib/screens/patients/profile/referral/AddReplayOnReferralPatient.dart @@ -1,7 +1,7 @@ import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/model/referral/add_referred_remarks_request.dart'; import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; @@ -19,12 +19,18 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; +import 'ReplySummeryOnReferralPatient.dart'; + class AddReplayOnReferralPatient extends StatefulWidget { final PatientReferralViewModel patientReferralViewModel; final MyReferralPatientModel myReferralInPatientModel; + final AddReferredRemarksRequestModel myReferralInPatientRequestModel; + final bool isEdited; const AddReplayOnReferralPatient( - {Key? key, required this.patientReferralViewModel, required this.myReferralInPatientModel}) + {Key? key, required this.patientReferralViewModel, required this.myReferralInPatientModel, + this.isEdited, + this.myReferralInPatientRequestModel}) : super(key: key); @override @@ -33,14 +39,18 @@ class AddReplayOnReferralPatient extends StatefulWidget { class _AddReplayOnReferralPatientState extends State { bool isSubmitted = false; + int replay = 1; + int reject = 2; stt.SpeechToText speech = stt.SpeechToText(); var reconizedWord; var event = RobotProvider(); TextEditingController replayOnReferralController = TextEditingController(); + @override void initState() { requestPermissions(); super.initState(); + replayOnReferralController.text = widget.myReferralInPatientModel.referredDoctorRemarks ?? ""; } @override @@ -48,27 +58,26 @@ class _AddReplayOnReferralPatientState extends State return AppScaffold( isShowAppBar: false, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - body: SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.0, - child: Padding( - padding: EdgeInsets.all(0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BottomSheetTitle(title: 'Replay'), - SizedBox( - height: 10.0, - ), - Center( - child: FractionallySizedBox( - widthFactor: 0.9, - child: Column( - children: [ - Stack( - children: [ - AppTextFieldCustom( - hintText: 'Replay your responses here', + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BottomSheetTitle(title: 'Reply'), + SizedBox( + height: 10.0, + ), + Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + children: [ + Stack( + children: [ + AppTextFieldCustom( + hintText: 'Reply your responses here', controller: replayOnReferralController, maxLines: 35, minLines: 25, @@ -101,57 +110,153 @@ class _AddReplayOnReferralPatientState extends State ), ), ), - ), - bottomSheet: Container( - height: replayOnReferralController.text.isNotEmpty ? 130 : 70, - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Column( - children: [ - replayOnReferralController.text.isEmpty - ? SizedBox() - : Container( - margin: EdgeInsets.all(5), - child: Expanded( + Container( + // height: replayOnReferralController.text.isNotEmpty ? 130 : 70, + // margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Column( + children: [ + replayOnReferralController.text.isEmpty + ? SizedBox() + : Container( + margin: EdgeInsets.all(16), child: AppButton( - title: TranslationBase.of(context).clearText, - onPressed: () { - setState(() { - replayOnReferralController.text = ''; - }); - }, - )), + title: TranslationBase.of(context).clearText, + onPressed: () { + setState(() { + replayOnReferralController.text = ''; + }); + }, + ), + ), + Container( + margin: EdgeInsets.fromLTRB(16, 0, 16, 16), + child: Row( + children: [ + Expanded( + child: AppButton( + onPressed: () async { + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, reject); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + DrAppToastMsg.showSuccesToast("Has been rejected"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), + // ), + // ); + } + } else { + Helpers.showErrorToast("You can't add empty reply"); + setState(() { + isSubmitted = false; + }); + } + }, + title: TranslationBase.of(context).reject, + fontColor: Colors.white, + color: Colors.red[600], + ), + ), + SizedBox( + width: 4, + ), + Expanded( + child: AppButton( + onPressed: () async { + setState(() { + isSubmitted = true; + }); + if (replayOnReferralController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + await widget.patientReferralViewModel.replayReferred( + replayOnReferralController.text.trim(), widget.myReferralInPatientModel, replay); + if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { + Helpers.showErrorToast(widget.patientReferralViewModel.error); + } else { + GifLoaderDialogUtils.hideDialog(context); + DrAppToastMsg.showSuccesToast("Your Reply Added Successfully"); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, replayOnReferralController.text.trim()), + // ), + // ); + } + } else { + Helpers.showErrorToast("You can't add empty reply"); + setState(() { + isSubmitted = false; + }); + } + }, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + ), + ], ), - Container( - margin: EdgeInsets.all(5), - child: AppButton( - title: 'Submit Replay', - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - setState(() { - isSubmitted = true; - }); - if (replayOnReferralController.text.isNotEmpty) { - GifLoaderDialogUtils.showMyDialog(context); - await widget.patientReferralViewModel - .replay(replayOnReferralController.text.trim(), widget.myReferralInPatientModel); - if (widget.patientReferralViewModel.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(widget.patientReferralViewModel.error); - } else { - GifLoaderDialogUtils.hideDialog(context); - DrAppToastMsg.showSuccesToast("Your Replay Added Successfully"); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } - } else { - Helpers.showErrorToast("You can't add empty replay"); - setState(() { - isSubmitted = false; - }); - } - })), - ], - ), + ), + // Container( + // margin: EdgeInsets.all(5), + // child: AppButton( + // title: 'Submit Reply', + // color: Color(0xff359846), + // fontWeight: FontWeight.w700, + // onPressed: () async { + // setState(() { + // isSubmitted = true; + // }); + // if (replayOnReferralController.text.isNotEmpty) { + // GifLoaderDialogUtils.showMyDialog(context); + // await widget.patientReferralViewModel.replay( + // replayOnReferralController.text.trim(), + // widget.myReferralInPatientModel); + // if (widget.patientReferralViewModel.state == + // ViewState.ErrorLocal) { + // Helpers.showErrorToast( + // widget.patientReferralViewModel.error); + // } else { + // GifLoaderDialogUtils.hideDialog(context); + // DrAppToastMsg.showSuccesToast( + // "Your Reply Added Successfully"); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // + // Navigator.push( + // context, + // FadePage( + // page: ReplySummeryOnReferralPatient( + // widget.myReferralInPatientModel, + // replayOnReferralController.text.trim()), + // ), + // ); + // } + // } else { + // Helpers.showErrorToast("You can't add empty reply"); + // setState(() { + // isSubmitted = false; + // }); + // } + // })), + ], + ), + ), + ], ), ); } diff --git a/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart new file mode 100644 index 00000000..2a48e079 --- /dev/null +++ b/lib/screens/patients/profile/referral/ReplySummeryOnReferralPatient.dart @@ -0,0 +1,119 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/referral/MyReferralPatientModel.dart'; +import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:flutter/material.dart'; + +import '../../../../routes.dart'; + +class ReplySummeryOnReferralPatient extends StatefulWidget { + final MyReferralPatientModel referredPatient; + final String doctorReply; + + ReplySummeryOnReferralPatient(this.referredPatient, this.doctorReply); + + @override + _ReplySummeryOnReferralPatientState createState() => + _ReplySummeryOnReferralPatientState(this.referredPatient); +} + +class _ReplySummeryOnReferralPatientState + extends State { + final MyReferralPatientModel referredPatient; + + _ReplySummeryOnReferralPatientState(this.referredPatient); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).summeryReply, + body: Container( + child: Column( + children: [ + + Expanded( + child: SingleChildScrollView( + child: Container( + width: double.infinity, + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + widget.doctorReply ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), + ), + ), + ), + Container( + margin: + EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Row( + children: [ + Expanded( + child: AppButton( + onPressed: () { + Navigator.of(context).pop(); + }, + title: TranslationBase.of(context).cancel, + fontColor: Colors.white, + color: Colors.red[600], + ), + ), + SizedBox(width: 4,), + Expanded( + child: AppButton( + onPressed: () {}, + title: TranslationBase.of(context).noteConfirm, + fontColor: Colors.white, + color: Colors.green[600], + ), + ), + ], + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart index 40e263f3..74d8d3b1 100644 --- a/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart +++ b/lib/screens/patients/profile/referral/my-referral-inpatient-screen.dart @@ -1,16 +1,21 @@ +import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referral_patient_detail_in-paint.dart'; +import 'package:doctor_app_flutter/screens/patients/profile/referral/referred-patient-screen.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/patient-referral-item-widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class MyReferralInPatientScreen extends StatelessWidget { + PatientType patientType = PatientType.IN_PATIENT; + @override Widget build(BuildContext context) { return BaseView( @@ -19,34 +24,48 @@ class MyReferralInPatientScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: false, appBarTitle: TranslationBase.of(context).referPatient ?? "", - body: model.myReferralPatients.isEmpty - ? Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 100, + body: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 70), + child: PatientTypeRadioWidget( + (patientType) async { + this.patientType = patientType; + GifLoaderDialogUtils.showMyDialog(context); + if (patientType == PatientType.IN_PATIENT) { + await model.getMyReferralPatientService(localBusy: true); + } else { + await model.getMyReferralOutPatientService(localBusy: true); + } + GifLoaderDialogUtils.hideDialog(context); + }, + ), + ), + model.myReferralPatients.isEmpty + ? Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: 100, + ), + Image.asset('assets/images/no-data.png'), + Padding( + padding: const EdgeInsets.all(8.0), + child: AppText( + TranslationBase.of(context).referralEmptyMsg, + color: Theme.of(context).errorColor, + ), + ) + ], ), - Image.asset('assets/images/no-data.png'), - Padding( - padding: const EdgeInsets.all(8.0), - child: AppText( - TranslationBase.of(context).referralEmptyMsg, - color: Theme.of(context).errorColor, - ), - ) - ], - ), - ) - : SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 70), - // color: Colors.white, - // height: MediaQuery.of(context).size.height, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // SizedBox(height: 50), + ) + : Expanded( + child: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ ...List.generate( model.myReferralPatients.length, (index) => InkWell( @@ -66,7 +85,7 @@ class MyReferralInPatientScreen extends StatelessWidget { patientGender: model.myReferralPatients[index].gender, referredDate: AppDateUtils.getDayMonthYearDateFormatted( model.myReferralPatients[index].referralDate!), - referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate!), + referredTime: AppDateUtils.getTimeHHMMA(model.myReferralPatients[index].referralDate!), patientID: "${model.myReferralPatients[index].patientID}", isSameBranch: false, isReferral: true, @@ -85,7 +104,9 @@ class MyReferralInPatientScreen extends StatelessWidget { ], ), ), - ), + ),), + ], + ), ), ); } diff --git a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart index 8b066cbe..f062d8c1 100644 --- a/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart +++ b/lib/screens/patients/profile/referral/refer-patient-screen-in-patient.dart @@ -5,10 +5,10 @@ import 'package:doctor_app_flutter/core/provider/robot_provider.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; @@ -136,12 +136,8 @@ class _PatientMakeInPatientReferralScreenState extends State { baseViewModel: model, appBarTitle: TranslationBase.of(context).referPatient!, isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), body: SingleChildScrollView( child: Container( child: Column( diff --git a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart index 1e48aafd..7d6bdb08 100644 --- a/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referral_patient_detail_in-paint.dart @@ -142,7 +142,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { fontWeight: FontWeight.w700, color: referredPatient.referralStatus == 1 ? Color(0xffc4aa54) - : referredPatient.referralStatus == 46 + : referredPatient.referralStatus == 46 || referredPatient.referralStatus == 2 ? Colors.green[700] : Colors.red[700], ), @@ -199,6 +199,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { children: [ Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( "${TranslationBase.of(context).refClinic}: ", @@ -207,16 +208,18 @@ class ReferralPatientDetailScreen extends StatelessWidget { fontSize: 1.7 * SizeConfig.textMultiplier, color: Color(0XFF575757), ), - AppText( - referredPatient.referringClinicDescription, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + Expanded( + child: AppText( + referredPatient.referringClinicDescription, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), - Row( + if (referredPatient.frequency != null)Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -229,7 +232,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - referredPatient.frequencyDescription, + referredPatient.frequencyDescription?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -268,12 +271,13 @@ class ReferralPatientDetailScreen extends StatelessWidget { ) ], ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).priority! + ": ", + if (referredPatient.priorityDescription != null) + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).priority! + ": ", fontFamily: 'Poppins', fontWeight: FontWeight.w600, fontSize: 1.7 * SizeConfig.textMultiplier, @@ -281,7 +285,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - referredPatient.priorityDescription, + referredPatient.priorityDescription?? '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -289,7 +293,7 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), ), ], - ), + ),if (referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -302,9 +306,9 @@ class ReferralPatientDetailScreen extends StatelessWidget { color: Color(0XFF575757), ), Expanded( - child: AppText( - AppDateUtils.convertDateFromServerFormat( - referredPatient.mAXResponseTime!, "dd MMM,yyyy"), + child: AppText(referredPatient.mAXResponseTime != null + ? AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime!, "dd MMM,yyyy"): '', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -386,67 +390,110 @@ class ReferralPatientDetailScreen extends StatelessWidget { ), Expanded( child: SingleChildScrollView( - child: Container( - width: double.infinity, - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - border: Border.fromBorderSide(BorderSide( - color: Colors.white, - width: 1.0, - )), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).remarks, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 2.4 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + children: [ + Container( + width: double.infinity, + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), ), - AppText( - referredPatient.referringDoctorRemarks, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).remarks, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referringDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], ), - SizedBox( - height: 8, + ), + if (referredPatient.referredDoctorRemarks.isNotEmpty) + Container( + width: double.infinity, + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 0), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + border: Border.fromBorderSide(BorderSide( + color: Colors.white, + width: 1.0, + )), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).reply, + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 2.4 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + AppText( + referredPatient.referredDoctorRemarks ?? '', + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), + SizedBox( + height: 8, + ), + ], + ), ), - ], - ), + ], ), ), ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), - child: AppButton( - title: TranslationBase.of(context).replay, - color: Colors.red[700], - fontColor: Colors.white, - fontWeight: FontWeight.w700, - fontSize: 1.8, - hPadding: 8, - vPadding: 12, - onPressed: () async { - Navigator.push( - context, - SlideUpPageRoute( - widget: AddReplayOnReferralPatient( - patientReferralViewModel: patientReferralViewModel, - myReferralInPatientModel: referredPatient, + if (referredPatient.referralStatus == 1) + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: AppButton( + title: TranslationBase.of(context).replay, + color: Colors.red[700], + fontColor: Colors.white, + fontWeight: FontWeight.w700, + fontSize: 1.8, + hPadding: 8, + vPadding: 12, + onPressed: () async { + Navigator.push( + context, + SlideUpPageRoute( + widget: AddReplayOnReferralPatient( + patientReferralViewModel: patientReferralViewModel, + myReferralInPatientModel: referredPatient, + isEdited: referredPatient.referredDoctorRemarks.isNotEmpty, + ), ), - ), - ); - }, + ); + }, + ), ), - ), ], ), ), diff --git a/lib/screens/patients/profile/referral/referred-patient-screen.dart b/lib/screens/patients/profile/referral/referred-patient-screen.dart index 4f9e0dcb..c94de944 100644 --- a/lib/screens/patients/profile/referral/referred-patient-screen.dart +++ b/lib/screens/patients/profile/referral/referred-patient-screen.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/core/enum/PatientType.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-referral-viewmodel.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/referral/referred_patient_detail_in-paint.dart'; @@ -6,12 +7,15 @@ import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/patient-referral-item-widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:doctor_app_flutter/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class ReferredPatientScreen extends StatelessWidget { - // previous design page is: MyReferredPatient + + PatientType patientType = PatientType.IN_PATIENT; + @override Widget build(BuildContext context) { return BaseView( @@ -20,7 +24,23 @@ class ReferredPatientScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: false, appBarTitle: TranslationBase.of(context).referredPatient!, - body: model.listMyReferredPatientModel == null || model.listMyReferredPatientModel.length == 0 + body: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 70), + child: PatientTypeRadioWidget( + (patientType) async { + this.patientType = patientType; + GifLoaderDialogUtils.showMyDialog(context); + if (patientType == PatientType.IN_PATIENT) { + await model.getMyReferredPatient(isFirstTime: false); + } else { + await model.getMyReferredOutPatient(isFirstTime: false); + } + GifLoaderDialogUtils.hideDialog(context); + }, + ), + ),model.listMyReferredPatientModel == null || model.listMyReferredPatientModel.length == 0 ? Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -39,19 +59,13 @@ class ReferredPatientScreen extends StatelessWidget { ], ), ) - : SingleChildScrollView( - // DoctorApplication.svc/REST/GtMyReferredPatient - child: Container( - margin: EdgeInsets.only(top: 70), - child: Column( - children: [ - // const Divider( - // color: Color(0xffCCCCCC), - // height: 1, - // thickness: 2, - // indent: 0, - // endIndent: 0, - // ), + : Expanded( + child: SingleChildScrollView( + // DoctorApplication.svc/REST/GtMyReferredPatient + child: Container( + child: Column( + children: [ + ...List.generate( model.listMyReferredPatientModel.length, (index) => InkWell( @@ -88,10 +102,64 @@ class ReferredPatientScreen extends StatelessWidget { ), ), ], - ), + ),), + ), ), - ), + ], + ), ), ); } } + +class PatientTypeRadioWidget extends StatefulWidget { + final Function(PatientType) radioOnChange; + + PatientTypeRadioWidget(this.radioOnChange); + + @override + _PatientTypeRadioWidgetState createState() => + _PatientTypeRadioWidgetState(this.radioOnChange); +} + +class _PatientTypeRadioWidgetState extends State { + final Function(PatientType) radioOnChange; + + _PatientTypeRadioWidgetState(this.radioOnChange); + + PatientType patientType = PatientType.IN_PATIENT; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: RadioListTile( + title: AppText(TranslationBase.of(context).inPatient), + value: PatientType.IN_PATIENT, + groupValue: patientType, + onChanged: (PatientType value) { + setState(() { + patientType = value; + radioOnChange(value); + }); + }, + ), + ), + Expanded( + child: RadioListTile( + title: AppText(TranslationBase.of(context).outpatient), + value: PatientType.OUT_PATIENT, + groupValue: patientType, + onChanged: (PatientType value) { + setState(() { + patientType = value; + radioOnChange(value); + }); + }, + ), + ), + ], + ); + } +} diff --git a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart index bd722b59..7e99f2e2 100644 --- a/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart +++ b/lib/screens/patients/profile/referral/referred_patient_detail_in-paint.dart @@ -216,6 +216,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient + .frequencyDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -268,6 +270,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ) ], ), + if(referredPatient.priorityDescription != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -288,6 +291,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), ], ), + if(referredPatient.mAXResponseTime != null) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -301,8 +305,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { ), Expanded( child: AppText( - AppDateUtils.convertDateFromServerFormat( - referredPatient.mAXResponseTime ?? "", "dd MMM,yyyy"), + referredPatient.mAXResponseTime != null?AppDateUtils.convertDateFromServerFormat( + referredPatient.mAXResponseTime ?? "", "dd MMM,yyyy"):'', fontFamily: 'Poppins', fontWeight: FontWeight.w700, fontSize: 1.8 * SizeConfig.textMultiplier, @@ -455,7 +459,8 @@ class ReferredPatientDetailScreen extends StatelessWidget { color: Color(0XFF2E303A), ), AppText( - referredPatient.referredDoctorRemarks!.isNotEmpty + referredPatient + .referredDoctorRemarks == null ?'':referredPatient.referredDoctorRemarks!.isNotEmpty ? referredPatient.referredDoctorRemarks : TranslationBase.of(context).notRepliedYet, fontFamily: 'Poppins', @@ -483,7 +488,7 @@ class ReferredPatientDetailScreen extends StatelessWidget { fontSize: 1.8, hPadding: 8, vPadding: 12, - disabled: referredPatient.referredDoctorRemarks!.isNotEmpty ? false : true, + disabled: referredPatient.referredDoctorRemarks == null? true: referredPatient.referredDoctorRemarks!.isNotEmpty ? false : true, onPressed: () async { await model.verifyReferralDoctorRemarks(referredPatient); if (model.state == ViewState.ErrorLocal) { diff --git a/lib/screens/patients/profile/soap_update/update_soap_index.dart b/lib/screens/patients/profile/soap_update/update_soap_index.dart index 93fcff50..f646dbe9 100644 --- a/lib/screens/patients/profile/soap_update/update_soap_index.dart +++ b/lib/screens/patients/profile/soap_update/update_soap_index.dart @@ -5,9 +5,10 @@ import 'package:doctor_app_flutter/models/SOAP/my_selected_assement.dart'; import 'package:doctor_app_flutter/models/SOAP/my_selected_examination.dart'; import 'package:doctor_app_flutter/models/SOAP/my_selected_history.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/subjective/update_subjective_page.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -78,10 +79,10 @@ class _UpdateSoapIndexState extends State with TickerProviderSt mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - PatientProfileHeaderNewDesign( - patient, - '7', - '7', + PatientProfileAppBar( + patientProfileAppBarModel: + PatientProfileAppBarModel( + patient: patient), ), Container( width: double.infinity, diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart index c2ff0c34..1c088af2 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_details_screen.dart @@ -2,11 +2,11 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/patient-vital-sign-viewmodel.dart'; import 'package:doctor_app_flutter/lookups/patient_lookup.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/errors/error_message.dart'; @@ -38,7 +38,7 @@ class VitalSignDetailsScreen extends StatelessWidget { baseViewModel: mode, isShowAppBar: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), appBarTitle: TranslationBase.of(context).vitalSign!, body: mode.patientVitalSignsHistory.length > 0 ? Column( diff --git a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart index ad0dc1a7..f71306aa 100644 --- a/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart +++ b/lib/screens/patients/profile/vital_sign/vital_sign_item_details_screen.dart @@ -2,12 +2,12 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/lookups/patient_lookup.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/models/patient/vital_sign/patient-vital-sign-history.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sign_detail_pain_scale.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sing_chart_and_detials.dart'; import 'package:doctor_app_flutter/screens/patients/profile/vital_sign/vital_sing_chart_blood_pressure.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -190,7 +190,9 @@ class VitalSignItemDetailsScreen extends StatelessWidget { appBarTitle: pageTitle ?? "", backgroundColor: Color.fromRGBO(248, 248, 248, 1), isShowAppBar: true, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patientType, arrivalType), + + + patientProfileAppBarModel: PatientProfileAppBarModel(patient:patient), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/screens/prescription/add_favourite_prescription.dart b/lib/screens/prescription/add_favourite_prescription.dart deleted file mode 100644 index e3a5a654..00000000 --- a/lib/screens/prescription/add_favourite_prescription.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/prescription/prescription_checkout_screen.dart'; -import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class AddFavPrescription extends StatefulWidget { - final PrescriptionViewModel? model; - final PatiantInformtion? patient; - final String? categoryID; - - const AddFavPrescription({Key? key, this.model, this.patient, this.categoryID}) : super(key: key); - - @override - _AddFavPrescriptionState createState() => _AddFavPrescriptionState(); -} - -class _AddFavPrescriptionState extends State { - late MedicineViewModel model; - late PatiantInformtion patient; - - List entityList = []; - late ProcedureTempleteDetailsModel groupProcedures; - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getProcedureTemplate(categoryID: widget.categoryID), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - baseViewModel: model, - body: Column( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.070, - ), - if (model.templateList.length != 0) - Expanded( - child: NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchFavProceduresWidget( - isProcedure: false, - model: model, - removeFavProcedure: (item) { - setState(() { - entityList.remove(item); - }); - }, - addFavProcedure: (history) { - setState(() { - entityList.add(history); - }); - }, - isEntityFavListSelected: (master) => isEntityListSelected(master), - groupProcedures: groupProcedures, - selectProcedures: (valasd) { - setState(() { - groupProcedures = valasd; - }); - }, - ), - ), - ), - Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: 'Add Selected Prescription', - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () { - if (groupProcedures == null) { - DrAppToastMsg.showErrorToast( - 'Please Select item ', - ); - return; - } - - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PrescriptionCheckOutScreen( - patient: widget.patient!, - model: widget.model!, - groupProcedures: groupProcedures, - ), - ), - ); - }, - ), - ], - ), - ), - ], - ), - ), - ); - } - - bool isEntityListSelected(ProcedureTempleteDetailsModel masterKey) { - Iterable history = entityList.where( - (element) => masterKey.templateID == element.templateID && masterKey.procedureName == element.procedureName); - if (history.length > 0) { - return true; - } - return false; - } -} diff --git a/lib/screens/prescription/add_prescription_form.dart b/lib/screens/prescription/add_prescription_form.dart index 260baee4..cc6a87be 100644 --- a/lib/screens/prescription/add_prescription_form.dart +++ b/lib/screens/prescription/add_prescription_form.dart @@ -148,8 +148,16 @@ class _PrescriptionFormWidgetState extends State { @override void initState() { - super.initState(); + requestPermissions(); + event.controller.stream.listen((p) { + if (p['startPopUp'] == 'true') { + if (this.mounted) { + initSpeechState().then((value) => {onVoiceText()}); + } + } + }); selectedType = 1; + super.initState(); } setSelectedType(int val) { @@ -196,7 +204,7 @@ class _PrescriptionFormWidgetState extends State { setState(() { SpeechToText.closeAlertDialog(context); speech.stop(); - indicationController.text += reconizedWord + '\n'; + instructionController.text += reconizedWord + '\n'; }); } else { print(result.finalResult); @@ -263,25 +271,6 @@ class _PrescriptionFormWidgetState extends State { SizedBox( height: 60, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - TranslationBase.of(context).newPrescriptionOrder, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ], - ), ], ), SizedBox( @@ -433,7 +422,7 @@ class _PrescriptionFormWidgetState extends State { ), PrescriptionTextFiled( isSubmitted: isSubmitted, - width: MediaQuery.of(context).size.width * 0.560, + width: MediaQuery.of(context).size.width * 0.517, element: model.itemMedicineListUnit.length == 1 ? units = model.itemMedicineListUnit[0] : units, @@ -533,7 +522,7 @@ class _PrescriptionFormWidgetState extends State { ), ), Container( - width: MediaQuery.of(context).size.width * 0.65, + width: MediaQuery.of(context).size.width * 0.59, color: Colors.white, child: TextField( maxLines: 5, @@ -645,9 +634,7 @@ class _PrescriptionFormWidgetState extends State { size: 35, ), onPressed: () { - setState(() { - initSpeechState().then((value) => {onVoiceText()}); - }); + initSpeechState().then((value) => {onVoiceText()}); }, ), ), diff --git a/lib/screens/prescription/prescription_checkout_screen.dart b/lib/screens/prescription/prescription_checkout_screen.dart index a631ab15..e57982cf 100644 --- a/lib/screens/prescription/prescription_checkout_screen.dart +++ b/lib/screens/prescription/prescription_checkout_screen.dart @@ -136,8 +136,16 @@ class _PrescriptionCheckOutScreenState extends State @override void initState() { - super.initState(); + requestPermissions(); + event.controller.stream.listen((p) { + if (p['startPopUp'] == 'true') { + if (this.mounted) { + initSpeechState().then((value) => {onVoiceText()}); + } + } + }); selectedType = 1; + super.initState(); } onVoiceText() async { @@ -512,29 +520,7 @@ class _PrescriptionCheckOutScreenState extends State }, ), SizedBox(height: spaceBetweenTextFileds), - // Container( - // color: Colors.white, - // child: AppTextFieldCustom( - // hintText: "UOM", - // isTextFieldHasSuffix: false, - // dropDownText: uom != null ? uom : null, - // enabled: false, - // ), - // ), SizedBox(height: spaceBetweenTextFileds), - // Container( - // color: Colors.white, - // child: AppTextFieldCustom( - // hintText: TranslationBase.of(context).boxQuantity, - // isTextFieldHasSuffix: false, - // dropDownText: box != null - // ? TranslationBase.of(context).boxQuantity + - // ": " + - // model.boxQuintity.toString() - // : null, - // enabled: false, - // ), - // ), SizedBox(height: spaceBetweenTextFileds), Container( decoration: BoxDecoration( @@ -559,9 +545,7 @@ class _PrescriptionCheckOutScreenState extends State size: 35, ), onPressed: () { - setState(() { - initSpeechState().then((value) => {onVoiceText()}); - }); + initSpeechState().then((value) => {onVoiceText()}); }, ), ), diff --git a/lib/screens/prescription/prescription_home_screen.dart b/lib/screens/prescription/prescription_home_screen.dart deleted file mode 100644 index eeeb07ef..00000000 --- a/lib/screens/prescription/prescription_home_screen.dart +++ /dev/null @@ -1,203 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/prescription/add_favourite_prescription.dart'; -import 'package:doctor_app_flutter/screens/prescription/add_prescription_form.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/material.dart'; - -class PrescriptionHomeScreen extends StatefulWidget { - final PrescriptionViewModel model; - final PatiantInformtion patient; - - const PrescriptionHomeScreen({Key? key, required this.model, required this.patient}) : super(key: key); - @override - _PrescriptionHomeScreenState createState() => _PrescriptionHomeScreenState(); -} - -class _PrescriptionHomeScreenState extends State with SingleTickerProviderStateMixin { - late PrescriptionViewModel model; - late PatiantInformtion patient; - late TabController _tabController; - int _activeTab = 0; - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - _tabController.addListener(_handleTabSelection); - } - - @override - void dispose() { - super.dispose(); - _tabController.dispose(); - } - - _handleTabSelection() { - setState(() { - _activeTab = _tabController.index; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - //onModelReady: (model) => model.getCategory(), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(children: [ - InkWell( - child: Icon( - Icons.arrow_back_ios, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ), - SizedBox( - width: 7.0, - ), - AppText( - 'Add prescription', - fontWeight: FontWeight.w700, - fontSize: 20, - ), - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Expanded( - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.070), - child: Container( - height: MediaQuery.of(context).size.height * 0.070, - decoration: BoxDecoration( - border: Border( - bottom: - BorderSide(color: Theme.of(context).dividerColor, width: 0.5), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorColor: Colors.transparent, - indicatorWeight: 1.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - tabWidget( - screenSize, - _activeTab == 0, - "Favorite Templates", - ), - tabWidget( - screenSize, - _activeTab == 1, - 'All Prescription', - ), - ], - ), - ), - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AddFavPrescription( - model: widget.model, - patient: widget.patient, - categoryID: '55', - ), - PrescriptionFormWidget( - widget.model, widget.patient, widget.model.prescriptionList), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ), - ), - ); - } - - Widget tabWidget(Size screenSize, bool isActive, String title, {int counter = -1}) { - return Center( - child: Container( - height: screenSize.height * 0.070, - decoration: TextFieldsUtils.containerBorderDecoration( - isActive ? Color(0xFFD02127 /*B8382B*/) : Color(0xFFEAEAEA), - isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), - borderRadius: 4, - borderWidth: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - title, - fontSize: SizeConfig.textMultiplier * 1.5, - color: isActive ? Colors.white : Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - if (counter != -1) - Container( - margin: EdgeInsets.all(4), - width: 15, - height: 15, - decoration: BoxDecoration( - color: isActive ? Colors.white : Color(0xFFD02127), - shape: BoxShape.circle, - ), - child: Center( - child: FittedBox( - child: AppText( - "$counter", - fontSize: SizeConfig.textMultiplier * 1.5, - color: !isActive ? Colors.white : Color(0xFFD02127), - fontWeight: FontWeight.w700, - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/prescription/prescription_item_in_patient_page.dart b/lib/screens/prescription/prescription_item_in_patient_page.dart index ffb9cee1..4429199a 100644 --- a/lib/screens/prescription/prescription_item_in_patient_page.dart +++ b/lib/screens/prescription/prescription_item_in_patient_page.dart @@ -2,10 +2,10 @@ import 'package:doctor_app_flutter/core/model/Prescriptions/prescription_in_pati import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; @@ -44,7 +44,8 @@ class PrescriptionItemsInPatientPage extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100]!, baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar(patient, patient.patientType.toString(), patient.arrivedOn ?? ""), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:patient), body: SingleChildScrollView( child: Container( child: Column( diff --git a/lib/screens/prescription/prescription_items_page.dart b/lib/screens/prescription/prescription_items_page.dart index 36434d43..2d1d5c4d 100644 --- a/lib/screens/prescription/prescription_items_page.dart +++ b/lib/screens/prescription/prescription_items_page.dart @@ -1,10 +1,10 @@ import 'package:doctor_app_flutter/core/model/Prescriptions/Prescriptions.dart'; import 'package:doctor_app_flutter/core/viewModel/prescriptions_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/dialogs/ShowImageDialog.dart'; @@ -32,16 +32,16 @@ class PrescriptionItemsPage extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100]!, baseViewModel: model, - appBar: PatientProfileHeaderWhitAppointmentAppBar( + patientProfileAppBarModel: PatientProfileAppBarModel( patient: patient, - patientType: patientType ?? "0", - arrivalType: arrivalType ?? "0", clinic: prescriptions.clinicDescription, branch: prescriptions.name, isPrescriptions: true, - appointmentDate: AppDateUtils.getDateTimeFromServerFormat(prescriptions.appointmentDate!), + appointmentDate: AppDateUtils.getDateTimeFromServerFormat( + prescriptions.appointmentDate!), doctorName: prescriptions.doctorName, profileUrl: prescriptions.doctorImageURL, + isAppointmentHeader: true, ), body: SingleChildScrollView( child: Container( diff --git a/lib/screens/prescription/prescription_screen.dart b/lib/screens/prescription/prescription_screen.dart deleted file mode 100644 index 3a1a058d..00000000 --- a/lib/screens/prescription/prescription_screen.dart +++ /dev/null @@ -1,593 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/prescription/add_prescription_form.dart'; -import 'package:doctor_app_flutter/screens/prescription/update_prescription_form.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionScreen extends StatefulWidget { - @override - _NewPrescriptionScreenState createState() => _NewPrescriptionScreenState(); -} - -class _NewPrescriptionScreenState extends State { - late PersistentBottomSheetController _controller; - final _scaffoldKey = GlobalKey(); - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - late int strengthChar; - late PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context)!.settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: (BuildContext context, PrescriptionViewModel model, Widget? child) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription ?? "", - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox(height: model.prescriptionList[0].rowcount == 0 ? 200.0 : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - InkWell( - child: Container( - height: 50.0, - width: 450.0, - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.grey), - borderRadius: BorderRadius.circular(10.0), - ), - child: Padding( - padding: EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppText( - ' Add more medication', - fontWeight: FontWeight.w100, - fontSize: 12.5, - ), - Icon( - Icons.add, - color: Color(0XFFB8382C), - ) - ], - ), - ), - ), - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - ), - SizedBox( - height: 10.0, - ), - ...List.generate( - model.prescriptionList[0].rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.022, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.21, - width: MediaQuery.of(context).size.width * 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList![index] - .createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList![index].createdOn) - .year) - .toString() - : DateTime.now().year) - .toString(), - color: Colors.green, - fontSize: 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0] - .entityList![index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList![index].createdOn) - .month) - : DateTime.now().month) - .toUpperCase(), - color: Colors.green, - ), - AppText( - DateTime.parse(model - .prescriptionList[0].entityList![index].createdOn) - .day - .toString(), - color: Colors.green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[0].entityList![index].createdOn)) - .toString(), - color: Colors.green, - ), - ], - ), - ), - Container( - color: Colors.white, - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of(context).size.width * 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0].entityList![index].startDate)), - fontSize: 13.5, - ), - ), - SizedBox( - width: 6.0, - ), - AppText( - 'Order Type:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index] - .orderTypeDescription, - fontSize: 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - color: Colors.white, - child: Expanded( - child: AppText( - model.prescriptionList[0].entityList![index] - .medicationName, - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index].doseDetail, - fontSize: 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model - .prescriptionList[0].entityList![index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .quantity - .toString() == - null - ? "" - : model.prescriptionList[0].entityList![index] - .quantity - .toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .pharmacyInervention == - null - ? "" - : model.prescriptionList[0].entityList![index] - .pharmacyInervention - .toString()), - ), - ), - ], - ), - SizedBox(height: 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - Expanded( - child: AppText( - // commening below code because there is an error coming in the model please fix it before pushing it - model.prescriptionList[0].entityList![index] - .pharmacistRemarks == - null - ? "" - : model.prescriptionList[0].entityList![index] - .pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context).doctorName! + ": ", - fontWeight: FontWeight.w600, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index].doctorName, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 13.0, - ), - Expanded( - child: Container( - color: Colors.white, - // height: MediaQuery.of(context).size.height * - // 0.038, - child: RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 10.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .remarks != - null - ? model.prescriptionList[0].entityList![index] - .remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.16, - width: MediaQuery.of(context).size.width * 0.06, - child: Column( - children: [ - InkWell( - child: Icon(Icons.edit), - onTap: () { - updatePrescriptionForm( - box: model - .prescriptionList[0].entityList![index].quantity, - uom: model.prescriptionList[0].entityList![index].uom, - drugNameGeneric: model.prescriptionList[0] - .entityList![index].medicationName, - doseUnit: model.prescriptionList[0].entityList![index] - .doseDailyUnitID - .toString(), - doseStreangth: model.prescriptionList[0] - .entityList![index].doseDailyQuantity - .toString(), - duration: model.prescriptionList[0].entityList![index] - .doseDurationDays - .toString(), - startDate: model - .prescriptionList[0].entityList![index].startDate - .toString(), - dose: model - .prescriptionList[0].entityList![index].doseTimingID - .toString(), - frequency: model - .prescriptionList[0].entityList![index].frequencyID - .toString(), - rouat: model.prescriptionList[0].entityList![index].routeID.toString(), - patient: patient, - drugId: model.prescriptionList[0].entityList![index].medicineCode, - drugName: model.prescriptionList[0].entityList![index].medicationName, - remarks: model.prescriptionList[0].entityList![index].remarks, - model: model, - enteredRemarks: model.prescriptionList[0].entityList![index].remarks, - context: context); - //model.postPrescription(); - }, - ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - InkWell( - onTap: () { - addPrescriptionForm(context, model, patient, model.prescriptionList); - //model.postPrescription(); - }, - child: CircleAvatar( - radius: 65, - backgroundColor: Color(0XFFB8382C), - child: CircleAvatar( - radius: 60, - backgroundColor: Colors.white, - child: Icon( - Icons.add, - color: Colors.black, - size: 45.0, - ), - ), - ), - ), - SizedBox( - height: 15.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).noPrescriptionListed, - color: Colors.black, - fontWeight: FontWeight.w900, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - TranslationBase.of(context).addNow, - color: Color(0XFFB8382C), - fontWeight: FontWeight.w900, - ), - ], - ), - ], - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime? picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/screens/prescription/prescription_screen_history.dart b/lib/screens/prescription/prescription_screen_history.dart deleted file mode 100644 index 5d9a07e0..00000000 --- a/lib/screens/prescription/prescription_screen_history.dart +++ /dev/null @@ -1,421 +0,0 @@ -import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-page-header-widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -class NewPrescriptionHistoryScreen extends StatefulWidget { - @override - _NewPrescriptionHistoryScreenState createState() => _NewPrescriptionHistoryScreenState(); -} - -class _NewPrescriptionHistoryScreenState extends State { - late PersistentBottomSheetController _controller; - final _scaffoldKey = GlobalKey(); - TextEditingController strengthController = TextEditingController(); - int testNum = 0; - late int strengthChar; - late PatiantInformtion patient; - - @override - void initState() { - super.initState(); - } - - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - final routeArgs = ModalRoute.of(context)!.settings.arguments as Map; - patient = routeArgs['patient']; - return BaseView( - onModelReady: (model) => model.getPrescription(mrn: patient.patientId), - builder: (BuildContext context, PrescriptionViewModel model, Widget? child) => AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).prescription ?? "", - body: NetworkBaseView( - baseViewModel: model, - child: SingleChildScrollView( - child: Container( - color: Colors.white, - child: Column( - children: [ - PatientPageHeaderWidget(patient), - Divider( - height: 1.0, - thickness: 1.0, - color: Colors.grey, - ), - (model.prescriptionList.length != 0) - ? SizedBox(height: model.prescriptionList[0].rowcount == 0 ? 200.0 : 10.0) - : SizedBox(height: 200.0), - //model.prescriptionList == null - (model.prescriptionList.length != 0) - ? model.prescriptionList[0].rowcount == 0 - ? Container( - child: AppText( - 'Sorry , Theres no prescriptions for this patient', - color: Color(0xFFB9382C), - ), - ) - : Padding( - padding: EdgeInsets.all(14.0), - child: NetworkBaseView( - baseViewModel: model, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ...List.generate( - model.prescriptionList[0].rowcount, - (index) => Container( - color: Colors.white, - child: Column( - children: [ - SizedBox( - height: MediaQuery.of(context).size.height * 0.022, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: - // CrossAxisAlignment.start, - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.21, - width: MediaQuery.of(context).size.width * 0.1, - child: Column( - children: [ - AppText( - (DateTime.parse(model.prescriptionList[0].entityList![index] - .createdOn) != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList![index].createdOn) - .year) - .toString() - : DateTime.now().year) - .toString(), - color: Colors.green, - fontSize: 13.5, - ), - AppText( - AppDateUtils.getMonth(model.prescriptionList[0] - .entityList![index].createdOn != - null - ? (DateTime.parse(model.prescriptionList[0] - .entityList![index].createdOn) - .month) - : DateTime.now().month) - .toUpperCase(), - color: Colors.green, - ), - AppText( - DateTime.parse(model - .prescriptionList[0].entityList![index].createdOn) - .day - .toString(), - color: Colors.green, - ), - AppText( - AppDateUtils.getTimeFormated(DateTime.parse(model - .prescriptionList[0].entityList![index].createdOn)) - .toString(), - color: Colors.green, - ), - ], - ), - ), - Container( - // height: MediaQuery.of( - // context) - // .size - // .height * - // 0.3499, - width: MediaQuery.of(context).size.width * 0.77, - child: Column( - children: [ - Row( - children: [ - AppText( - 'Start Date:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - AppDateUtils.getDateFormatted(DateTime.parse(model - .prescriptionList[0].entityList![index].startDate)), - fontSize: 13.5, - ), - ), - SizedBox( - width: 6.0, - ), - AppText( - 'Order Type:', - fontWeight: FontWeight.w700, - fontSize: 14.0, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index] - .orderTypeDescription, - fontSize: 13.0, - ), - ), - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Container( - child: Expanded( - child: AppText( - model.prescriptionList[0].entityList![index] - .medicationName, - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - ), - ) - ], - ), - SizedBox( - height: 5.5, - ), - Row( - children: [ - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index].doseDetail, - fontSize: 15.0, - ), - ) - ], - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ - AppText( - 'Indication: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .indication), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'UOM: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model - .prescriptionList[0].entityList![index].uom), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'BOX Quantity: ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .quantity - .toString() == - null - ? "" - : model.prescriptionList[0].entityList![index] - .quantity - .toString()), - ), - ), - ], - ), - Row( - children: [ - AppText( - 'pharmacy Intervention ', - fontWeight: FontWeight.w700, - fontSize: 17.0, - ), - Expanded( - child: RichText( - maxLines: 3, - overflow: TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 12.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .pharmacyInervention == - null - ? "" - : model.prescriptionList[0].entityList![index] - .pharmacyInervention - .toString()), - ), - ), - ], - ), - SizedBox(height: 5.0), - Row( - children: [ - AppText( - 'pharmacist Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 15.0, - ), - Expanded( - child: AppText( - // commening below code because there is an error coming in the model please fix it before pushing it - model.prescriptionList[0].entityList![index] - .pharmacistRemarks == - null - ? "" - : model.prescriptionList[0].entityList![index] - .pharmacistRemarks, - fontSize: 15.0), - ) - ], - ), - SizedBox( - height: 20.0, - ), - Row( - children: [ - AppText( - TranslationBase.of(context).doctorName! + ": ", - fontWeight: FontWeight.w600, - ), - Expanded( - child: AppText( - model.prescriptionList[0].entityList![index].doctorName, - fontWeight: FontWeight.w700, - ), - ) - ], - ), - SizedBox( - height: 8.0, - ), - Row( - children: [ - AppText( - 'Doctor Remarks : ', - fontWeight: FontWeight.w700, - fontSize: 13.0, - ), - Expanded( - child: Container( - // height: MediaQuery.of(context).size.height * - // 0.038, - child: RichText( - // maxLines: - // 2, - // overflow: - // TextOverflow.ellipsis, - strutStyle: StrutStyle(fontSize: 10.0), - text: TextSpan( - style: TextStyle(color: Colors.black), - text: model.prescriptionList[0].entityList![index] - .remarks != - null - ? model.prescriptionList[0].entityList![index] - .remarks - : "", - ), - ), - ), - ), - ], - ), - SizedBox( - height: 10.0, - ), - - // SizedBox( - // height: 40, - // ), - ], - ), - ), - ], - ), - Divider( - height: 0, - thickness: 1.0, - color: Colors.grey, - ), - ], - ), - ), - ), - ], - ), - ), - ) - : Container( - child: AppText( - 'Sorry , theres no prescriptions listed for this patient', - color: Color(0xFFB9382C), - ), - ) - ], - ), - ), - ), - )), - ); - } - - selectDate(BuildContext context, PrescriptionViewModel model) async { - DateTime selectedDate; - selectedDate = DateTime.now(); - final DateTime? picked = await showDatePicker( - context: context, - initialDate: selectedDate, - firstDate: DateTime.now().add(Duration(hours: 2)), - lastDate: DateTime(2040), - initialEntryMode: DatePickerEntryMode.calendar, - ); - if (picked != null && picked != selectedDate) { - setState(() { - selectedDate = picked; - }); - } - } -} diff --git a/lib/screens/prescription/prescription_text_filed.dart b/lib/screens/prescription/prescription_text_filed.dart index f9803789..bcf67ec2 100644 --- a/lib/screens/prescription/prescription_text_filed.dart +++ b/lib/screens/prescription/prescription_text_filed.dart @@ -1,4 +1,3 @@ -import 'package:doctor_app_flutter/core/viewModel/medicine_view_model.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/dialogs/dailog-list-select.dart'; diff --git a/lib/screens/prescription/prescriptions_page.dart b/lib/screens/prescription/prescriptions_page.dart index 5bd469be..d30e7748 100644 --- a/lib/screens/prescription/prescriptions_page.dart +++ b/lib/screens/prescription/prescriptions_page.dart @@ -1,14 +1,14 @@ import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/prescription/add_prescription_form.dart'; -import 'package:doctor_app_flutter/screens/prescription/prescription_home_screen.dart'; import 'package:doctor_app_flutter/screens/prescription/prescription_item_in_patient_page.dart'; import 'package:doctor_app_flutter/screens/prescription/prescription_items_page.dart'; +import 'package:doctor_app_flutter/screens/procedures/ProcedureType.dart'; +import 'package:doctor_app_flutter/screens/procedures/base_add_procedure_tab_page.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/patients/profile/add-order/addNewOrder.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/doctor_card.dart'; @@ -35,12 +35,8 @@ class PrescriptionsPage extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - patientType ?? '0', - arrivalType, - isInpatient: isInpatient, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient:isInpatient,), body: patient.admissionNo == null ? FractionallySizedBox( widthFactor: 1.0, @@ -50,7 +46,8 @@ class PrescriptionsPage extends StatelessWidget { SizedBox( height: 12, ), - if (model.prescriptionsList.isNotEmpty && patient.patientStatusType != 43) + if (model.prescriptionsList.isNotEmpty && + patient.patientStatusType != 43) Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -70,7 +67,8 @@ class PrescriptionsPage extends StatelessWidget { ], ), ), - if (patient.patientStatusType != null && patient.patientStatusType == 43) + if (patient.patientStatusType != null && + patient.patientStatusType == 43) Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -90,20 +88,25 @@ class PrescriptionsPage extends StatelessWidget { ], ), ), - if ((patient.patientStatusType != null && patient.patientStatusType == 43) || + if ((patient.patientStatusType != null && + patient.patientStatusType == 43) || (isFromLiveCare && patient.appointmentNo != null)) AddNewOrder( onTap: () { Navigator.push( context, MaterialPageRoute( - builder: (context) => PrescriptionHomeScreen( + builder: (context) => + BaseAddProcedureTabPage( patient: patient, - model: model, + prescriptionModel: model, + procedureType: + ProcedureType.PRESCRIPTION, )), ); }, - label: TranslationBase.of(context).applyForNewPrescriptionsOrder ?? "", + label: TranslationBase.of(context) + .applyForNewPrescriptionsOrder ?? "", ), ...List.generate( model.prescriptionsList.length, @@ -112,7 +115,8 @@ class PrescriptionsPage extends StatelessWidget { context, FadePage( page: PrescriptionItemsPage( - prescriptions: model.prescriptionsList[index], + prescriptions: + model.prescriptionsList[index], patient: patient, patientType: patientType, arrivalType: arrivalType, @@ -120,16 +124,22 @@ class PrescriptionsPage extends StatelessWidget { ), ), child: DoctorCard( - doctorName: model.prescriptionsList[index].doctorName ?? "", - profileUrl: model.prescriptionsList[index].doctorImageURL ?? "", + doctorName: + model.prescriptionsList[index].doctorName ?? "", + profileUrl: model + .prescriptionsList[index].doctorImageURL ?? "", branch: model.prescriptionsList[index].name ?? "", - clinic: model.prescriptionsList[index].clinicDescription ?? "", + clinic: model.prescriptionsList[index] + .clinicDescription ?? "", isPrescriptions: true, - appointmentDate: AppDateUtils.getDateTimeFromServerFormat( - model.prescriptionsList[index].appointmentDate ?? "", + appointmentDate: + AppDateUtils.getDateTimeFromServerFormat( + model.prescriptionsList[index] + .appointmentDate ?? "", ), ))), - if (model.prescriptionsList.isEmpty && patient.patientStatusType != 43) + if (model.prescriptionsList.isEmpty && + patient.patientStatusType != 43) Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -140,7 +150,8 @@ class PrescriptionsPage extends StatelessWidget { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context).noPrescriptionsFound), + child: AppText(TranslationBase.of(context) + .noPrescriptionsFound), ) ], ), @@ -165,29 +176,38 @@ class PrescriptionsPage extends StatelessWidget { FadePage( page: PrescriptionItemsInPatientPage( prescriptionIndex: index, - prescriptions: model.inPatientPrescription[index], + prescriptions: model + .inPatientPrescription[index], patient: patient, patientType: patientType, arrivalType: arrivalType, - startOn: AppDateUtils.getDateTimeFromServerFormat( - model.inPatientPrescription[index].startDatetime ?? "", + startOn: AppDateUtils + .getDateTimeFromServerFormat( + model.inPatientPrescription[index] + .startDatetime ?? "", ), - stopOn: AppDateUtils.getDateTimeFromServerFormat( - model.inPatientPrescription[index].stopDatetime ?? "", + stopOn: AppDateUtils + .getDateTimeFromServerFormat( + model.inPatientPrescription[index] + .stopDatetime ?? "", ), ), ), ), child: InPatientDoctorCard( - doctorName: model.inPatientPrescription[index].itemDescription, + doctorName: model.inPatientPrescription[index] + .itemDescription, profileUrl: 'sss', branch: 'hamza', clinic: 'basheer', isPrescriptions: true, - appointmentDate: AppDateUtils.getDateTimeFromServerFormat( - model.inPatientPrescription[index].prescriptionDatetime ?? "", + appointmentDate: + AppDateUtils.getDateTimeFromServerFormat( + model.inPatientPrescription[index] + .prescriptionDatetime ?? "", ), - createdBy: model.inPatientPrescription[index].createdByName, + createdBy: model.inPatientPrescription[index] + .createdByName, ))), if (model.inPatientPrescription.length == 0) Center( @@ -200,7 +220,8 @@ class PrescriptionsPage extends StatelessWidget { Image.asset('assets/images/no-data.png'), Padding( padding: const EdgeInsets.all(8.0), - child: AppText(TranslationBase.of(context).noPrescriptionsFound), + child: AppText(TranslationBase.of(context) + .noPrescriptionsFound), ) ], ), diff --git a/lib/screens/procedures/ProcedureCard.dart b/lib/screens/procedures/ProcedureCard.dart index f110f931..611218c1 100644 --- a/lib/screens/procedures/ProcedureCard.dart +++ b/lib/screens/procedures/ProcedureCard.dart @@ -18,7 +18,7 @@ class ProcedureCard extends StatelessWidget { final int categoryID; final PatiantInformtion patient; final int doctorID; - + final bool isInpatient; const ProcedureCard({ Key? key, required this.onTap, @@ -26,7 +26,7 @@ class ProcedureCard extends StatelessWidget { required this.categoryID, this.categoryName, required this.patient, - required this.doctorID, + required this.doctorID, this.isInpatient = false, }) : super(key: key); @override @@ -126,36 +126,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).doctorName + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.doctorName.toString(), - // fontSize: 12, - // bold: true, - // ), - // ], - // ), - // Row( - // children: [ - // AppText( - // TranslationBase.of(context).clinic + ": ", - // //color: Colors.grey, - // fontSize: 12, - // color: Colors.grey, - // ), - // AppText( - // entityList.clinicDescription ?? "", - // bold: true, - // fontSize: 12, - // ), - // ], - // ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -212,27 +182,6 @@ class ProcedureCard extends StatelessWidget { ), ], ), - /*Container( - alignment: Alignment.centerRight, - child: InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: FlowChartPage( - filterName: entityList.procedureName, - patient: patient, - ), - ), - ); - }, - child: AppText( - TranslationBase.of(context).showMoreBtn, - textDecoration: TextDecoration.underline, - color: Colors.blue, - ), - ), - ),*/ Padding( padding: const EdgeInsets.all(8.0), child: Row( @@ -244,8 +193,7 @@ class ProcedureCard extends StatelessWidget { fontSize: 12, ), ), - if ((entityList.categoryID == 2 || entityList.categoryID == 4) && - doctorID == entityList.doctorID) + if ((entityList.categoryID == 2 || entityList.categoryID == 4) && doctorID == entityList.doctorID && !isInpatient) InkWell( child: Icon(DoctorApp.edit), onTap: onTap, diff --git a/lib/screens/procedures/ProcedureType.dart b/lib/screens/procedures/ProcedureType.dart new file mode 100644 index 00000000..28a72041 --- /dev/null +++ b/lib/screens/procedures/ProcedureType.dart @@ -0,0 +1,88 @@ +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; + +enum ProcedureType { + PROCEDURE, + LAB_RESULT, + RADIOLOGY, + PRESCRIPTION, +} + +extension procedureType on ProcedureType { + String getFavouriteTabName(BuildContext context) { + return TranslationBase.of(context).favoriteTemplates; + } + + String getAllLabelName(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).allProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).allLab; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).allRadiology; + case ProcedureType.PRESCRIPTION: + return TranslationBase.of(context).allPrescription; + default: + return ""; + } + } + + String getToolbarLabel(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).addProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).addLabOrder; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).addRadiologyOrder; + case ProcedureType.PRESCRIPTION: + return TranslationBase.of(context).addPrescription; + default: + return ""; + } + } + + String getAddButtonTitle(BuildContext context) { + switch (this) { + case ProcedureType.PROCEDURE: + return TranslationBase.of(context).addProcedures; + case ProcedureType.LAB_RESULT: + return TranslationBase.of(context).addLabOrder; + case ProcedureType.RADIOLOGY: + return TranslationBase.of(context).addRadiologyOrder; + case ProcedureType.PRESCRIPTION: + return TranslationBase.of(context).addPrescription; + default: + return ""; + } + } + + String getCategoryId() { + switch (this) { + case ProcedureType.PROCEDURE: + return null; + case ProcedureType.LAB_RESULT: + return "02"; + case ProcedureType.RADIOLOGY: + return "03"; + case ProcedureType.PRESCRIPTION: + return "55"; + default: + return null; + } + } + + String getCategoryName() { + switch (this) { + case ProcedureType.PROCEDURE: + return null; + case ProcedureType.LAB_RESULT: + return "Laboratory"; + case ProcedureType.RADIOLOGY: + return "Radiology"; + default: + return null; + } + } +} diff --git a/lib/screens/procedures/add-favourite-procedure.dart b/lib/screens/procedures/add-favourite-procedure.dart index 8fa3220e..04194d80 100644 --- a/lib/screens/procedures/add-favourite-procedure.dart +++ b/lib/screens/procedures/add-favourite-procedure.dart @@ -1,12 +1,10 @@ import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_templateModel.dart'; import 'package:doctor_app_flutter/core/model/procedure/procedure_template_details_model.dart'; +import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; -import 'package:doctor_app_flutter/screens/procedures/entity_list_checkbox_search_widget.dart'; +import 'package:doctor_app_flutter/screens/prescription/prescription_checkout_screen.dart'; import 'package:doctor_app_flutter/screens/procedures/entity_list_fav_procedure.dart'; import 'package:doctor_app_flutter/screens/procedures/procedure_checkout_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; @@ -17,20 +15,21 @@ import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'ProcedureType.dart'; + class AddFavouriteProcedure extends StatefulWidget { final ProcedureViewModel model; + final PrescriptionViewModel prescriptionModel; final PatiantInformtion patient; - final String? categoryID; - final String addButtonTitle; - final String toolbarTitle; + final ProcedureType procedureType; - AddFavouriteProcedure( - {Key? key, - required this.model, - required this.patient, - this.categoryID, - required this.addButtonTitle, - required this.toolbarTitle}); + AddFavouriteProcedure({ + Key key, + this.model, + this.prescriptionModel, + this.patient, + @required this.procedureType, + }); @override _AddFavouriteProcedureState createState() => _AddFavouriteProcedureState(); @@ -39,15 +38,18 @@ class AddFavouriteProcedure extends StatefulWidget { class _AddFavouriteProcedureState extends State { _AddFavouriteProcedureState({this.patient, this.model}); - ProcedureViewModel? model; - PatiantInformtion? patient; - List entityList = []; + ProcedureViewModel model; + PatiantInformtion patient; + List entityList = List(); + ProcedureTempleteDetailsModel groupProcedures; @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getProcedureTemplate(categoryID: widget.categoryID), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( + onModelReady: (model) => + model.getProcedureTemplate(categoryID: widget.procedureType.getCategoryId()), + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( isShowAppBar: false, baseViewModel: model, body: Column( @@ -57,22 +59,27 @@ class _AddFavouriteProcedureState extends State { ), if (model.templateList.length != 0) Expanded( - child: NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchFavProceduresWidget( - model: model, - removeFavProcedure: (item) { - setState(() { - entityList.remove(item); - }); - }, - addFavProcedure: (history) { - setState(() { - entityList.add(history); - }); - }, - isEntityFavListSelected: (master) => isEntityListSelected(master), - ), + child: EntityListCheckboxSearchFavProceduresWidget( + isProcedure: !(widget.procedureType == ProcedureType.PRESCRIPTION), + model: model, + removeFavProcedure: (item) { + setState(() { + entityList.remove(item); + }); + }, + addFavProcedure: (history) { + setState(() { + entityList.add(history); + }); + }, + isEntityFavListSelected: (master) => + isEntityListSelected(master), + groupProcedures: groupProcedures, + selectProcedures: (selectedProcedure) { + setState(() { + groupProcedures = selectedProcedure; + }); + }, ), ), Container( @@ -81,29 +88,50 @@ class _AddFavouriteProcedureState extends State { alignment: WrapAlignment.center, children: [ AppButton( - title: widget.addButtonTitle ?? TranslationBase.of(context).addSelectedProcedures, + title: widget.procedureType.getAddButtonTitle(context) ?? + TranslationBase.of(context).addSelectedProcedures, color: Color(0xff359846), fontWeight: FontWeight.w700, onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).fillTheMandatoryProcedureDetails, - ); - return; - } + if(widget.procedureType == ProcedureType.PRESCRIPTION){ + if (groupProcedures == null) { + DrAppToastMsg.showErrorToast( + 'Please Select item ', + ); + return; + } - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ProcedureCheckOutScreen( - items: entityList, - model: model, - patient: widget.patient, - addButtonTitle: widget.addButtonTitle, - toolbarTitle: widget.toolbarTitle, + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PrescriptionCheckOutScreen( + patient: widget.patient, + model: widget.prescriptionModel, + groupProcedures: groupProcedures, + ), + ), + ); + } else { + if (entityList.isEmpty == true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .fillTheMandatoryProcedureDetails, + ); + return; + } + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ProcedureCheckOutScreen( + items: entityList, + model: model, + patient: widget.patient, + addButtonTitle: widget.procedureType.getAddButtonTitle(context), + toolbarTitle: widget.procedureType.getToolbarLabel(context), + ), ), - ), - ); + ); + } }, ), ], diff --git a/lib/screens/procedures/add-procedure-form.dart b/lib/screens/procedures/add-procedure-form.dart deleted file mode 100644 index 6c633960..00000000 --- a/lib/screens/procedures/add-procedure-form.dart +++ /dev/null @@ -1,324 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; -import 'package:flutter/material.dart'; - -import 'entity_list_checkbox_search_widget.dart'; - -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -Future postProcedure( - {required ProcedureViewModel model, - required String remarks, - String? orderType, - required PatiantInformtion patient, - required List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = []; - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId!]; - List controls = []; - controls.add( - Controls(code: "remarks", controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: element.type ?? "1"), - ); - controlsProcedure.add(Procedures(category: element.categoryID, procedure: element.procedureId, controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList!.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN!); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getProcedure(mrn: patient.patientMRN); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast(model.valadteProcedureList[0].entityList![0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - -void addSelectedProcedure(context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedProcedure( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedProcedure extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - - const AddSelectedProcedure({Key? key, required this.model, required this.patient}) : super(key: key); - - @override - _AddSelectedProcedureState createState() => _AddSelectedProcedureState(patient: patient, model: model); -} - -class _AddSelectedProcedureState extends State { - int? selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - - _AddSelectedProcedureState({required this.patient, required this.model}); - - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = []; - List entityListProcedure = []; - TextEditingController procedureName = TextEditingController(); - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: Column( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.070, - ), - Expanded( - child: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppText( - TranslationBase.of(context).pleaseEnterProcedure, - fontWeight: FontWeight.w700, - fontSize: 20, - ), - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Row( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.79, - child: AppTextFieldCustom( - hintText: TranslationBase.of(context).searchProcedureHere, - isTextFieldHasSuffix: false, - - maxLines: 1, - minLines: 1, - hasBorder: true, - controller: procedureName, - // onSubmitted: (_) { - // model.getProcedureCategory( - // categoryName: procedureName.text); - // }, - onClick: () { - if (procedureName.text.isNotEmpty && procedureName.text.length >= 3) - model.getProcedureCategory( - patientId: patient.patientId, categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).atLeastThreeCharacters, - ); - }, - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.02, - ), - Expanded( - child: InkWell( - onTap: () { - if (procedureName.text.isNotEmpty && procedureName.text.length >= 3) - model.getProcedureCategory( - patientId: patient.patientId, categoryName: procedureName.text); - else - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).atLeastThreeCharacters, - ); - }, - child: Icon( - Icons.search, - size: 25.0, - ), - ), - ), - ], - ), - if (procedureName.text.isNotEmpty && model.procedureList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: widget.model.categoriesList[0].entityList!, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => isEntityListSelected(master), - )), - SizedBox( - height: 115.0, - ), - ], - ), - ), - ), - ); - }), - ), - ), - Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addSelectedProcedures, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () async { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).fillTheMandatoryProcedureDetails, - ); - return; - } - - - - //TODO Elham* check the static value - postProcedure( - orderType: selectedType==null?"1":selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - - Navigator.pop(context); - }, - ), - ], - ), - ), - ], - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList.where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, - {Icon? suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } -} diff --git a/lib/screens/procedures/add-procedure-page.dart b/lib/screens/procedures/add-procedure-page.dart new file mode 100644 index 00000000..e0b7374f --- /dev/null +++ b/lib/screens/procedures/add-procedure-page.dart @@ -0,0 +1,221 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; +import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/screens/base/base_view.dart'; +import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; +import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; +import 'package:flutter/material.dart'; + +import 'ProcedureType.dart'; +import 'entity_list_checkbox_search_widget.dart'; + +class AddProcedurePage extends StatefulWidget { + final ProcedureViewModel model; + final PatiantInformtion patient; + final ProcedureType procedureType; + + const AddProcedurePage( + {Key key, this.model, this.patient, @required this.procedureType}) + : super(key: key); + + @override + _AddProcedurePageState createState() => _AddProcedurePageState( + patient: patient, model: model, procedureType: this.procedureType); +} + +class _AddProcedurePageState extends State { + int selectedType; + ProcedureViewModel model; + PatiantInformtion patient; + ProcedureType procedureType; + + _AddProcedurePageState({this.patient, this.model, this.procedureType}); + + TextEditingController procedureController = TextEditingController(); + TextEditingController remarksController = TextEditingController(); + List entityList = List(); + List entityListProcedure = List(); + TextEditingController procedureName = TextEditingController(); + + dynamic selectedCategory; + + setSelectedType(int val) { + setState(() { + selectedType = val; + }); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) { + model.getProcedureCategory( + categoryName: procedureType.getCategoryName(), + categoryID: procedureType.getCategoryId(), + patientId: patient.patientId); + }, + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( + isShowAppBar: false, + body: Column( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.070, + ), + Expanded( + child: NetworkBaseView( + baseViewModel: model, + child: SingleChildScrollView( + child: Container( + child: Padding( + padding: EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (procedureType == ProcedureType.PROCEDURE) + Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + AppText( + TranslationBase.of(context) + .pleaseEnterProcedure, + fontWeight: FontWeight.w700, + fontSize: 20, + ), + ], + ), + SizedBox( + height: + MediaQuery.of(context).size.height * 0.02, + ), + Row( + children: [ + Container( + width: MediaQuery.of(context).size.width * + 0.79, + child: AppTextFieldCustom( + hintText: TranslationBase.of(context) + .searchProcedureHere, + isTextFieldHasSuffix: false, + maxLines: 1, + minLines: 1, + hasBorder: true, + controller: procedureName, + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width * + 0.02, + ), + Expanded( + child: InkWell( + onTap: () { + if (procedureName.text.isNotEmpty && + procedureName.text.length >= 3) + model.getProcedureCategory( + patientId: patient.patientId, + categoryName: + procedureName.text); + else + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .atLeastThreeCharacters, + ); + }, + child: Icon( + Icons.search, + size: 25.0, + ), + ), + ), + ], + ), + ], + ), + if ((procedureType == ProcedureType.PROCEDURE + ? procedureName.text.isNotEmpty + : true) && + model.categoriesList.length != 0) + NetworkBaseView( + baseViewModel: model, + child: EntityListCheckboxSearchWidget( + model: widget.model, + masterList: + model.categoriesList[0].entityList, + removeHistory: (item) { + setState(() { + entityList.remove(item); + }); + }, + addHistory: (history) { + setState(() { + entityList.add(history); + }); + }, + addSelectedHistories: () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: (master) => + isEntityListSelected(master), + )), + ], + ), + ), + ), + ), + ), + ), + Container( + margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), + child: Wrap( + alignment: WrapAlignment.center, + children: [ + AppButton( + title: procedureType.getAddButtonTitle(context), + fontWeight: FontWeight.w700, + color: Color(0xff359846), + onPressed: () async { + if (entityList.isEmpty == true) { + DrAppToastMsg.showErrorToast( + TranslationBase.of(context) + .fillTheMandatoryProcedureDetails, + ); + return; + } + + await this.model.preparePostProcedure( + orderType: selectedType.toString(), + entityList: entityList, + patient: patient, + remarks: remarksController.text); + Navigator.pop(context); + }, + ), + ], + ), + ), + ], + ), + ), + ); + } + + bool isEntityListSelected(EntityList masterKey) { + Iterable history = entityList + .where((element) => masterKey.procedureId == element.procedureId); + if (history.length > 0) { + return true; + } + return false; + } +} diff --git a/lib/screens/procedures/add_lab_home_screen.dart b/lib/screens/procedures/add_lab_home_screen.dart deleted file mode 100644 index c6a83538..00000000 --- a/lib/screens/procedures/add_lab_home_screen.dart +++ /dev/null @@ -1,207 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import 'add_lab_orders.dart'; - -class AddLabHomeScreen extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - const AddLabHomeScreen({Key? key, required this.model, required this.patient}) : super(key: key); - @override - _AddLabHomeScreenState createState() => _AddLabHomeScreenState(patient: patient, model: model); -} - -class _AddLabHomeScreenState extends State with SingleTickerProviderStateMixin { - _AddLabHomeScreenState({required this.patient, required this.model}); - ProcedureViewModel model; - PatiantInformtion patient; - late TabController _tabController; - int _activeTab = 0; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - _tabController.addListener(_handleTabSelection); - } - - @override - void dispose() { - super.dispose(); - _tabController.dispose(); - } - - _handleTabSelection() { - setState(() { - _activeTab = _tabController.index; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppText( - 'Add Procedure', - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Expanded( - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.070), - child: Container( - height: MediaQuery.of(context).size.height * 0.070, - decoration: BoxDecoration( - border: Border( - bottom: - BorderSide(color: Theme.of(context).dividerColor, width: 0.5), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorColor: Colors.transparent, - indicatorWeight: 1.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - tabWidget( - screenSize, - _activeTab == 0, - "Favorite Templates", - ), - tabWidget( - screenSize, - _activeTab == 1, - 'All Lab', - ), - ], - ), - ), - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AddFavouriteProcedure( - patient: patient, - model: model, - addButtonTitle: TranslationBase.of(context).addLabOrder!, - toolbarTitle: TranslationBase.of(context).applyForNewLabOrder!, - categoryID: "02", - ), - AddSelectedLabOrder( - model: model, - patient: patient, - ), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ), - ), - ); - } - - Widget tabWidget(Size screenSize, bool isActive, String title, {int counter = -1}) { - return Center( - child: Container( - height: screenSize.height * 0.070, - decoration: TextFieldsUtils.containerBorderDecoration( - isActive ? Color(0xFFD02127 /*B8382B*/) : Color(0xFFEAEAEA), - isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), - borderRadius: 4, - borderWidth: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - title, - fontSize: SizeConfig.textMultiplier * 1.5, - color: isActive ? Colors.white : Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - if (counter != -1) - Container( - margin: EdgeInsets.all(4), - width: 15, - height: 15, - decoration: BoxDecoration( - color: isActive ? Colors.white : Color(0xFFD02127), - shape: BoxShape.circle, - ), - child: Center( - child: FittedBox( - child: AppText( - "$counter", - fontSize: SizeConfig.textMultiplier * 1.5, - color: !isActive ? Colors.white : Color(0xFFD02127), - fontWeight: FontWeight.w700, - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/procedures/add_lab_orders.dart b/lib/screens/procedures/add_lab_orders.dart deleted file mode 100644 index 025387a1..00000000 --- a/lib/screens/procedures/add_lab_orders.dart +++ /dev/null @@ -1,250 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -import 'entity_list_checkbox_search_widget.dart'; - -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -postProcedure( - {required ProcedureViewModel model, - required String remarks, - required String orderType, - required PatiantInformtion patient, - required List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = []; - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId!]; - List controls = []; - controls.add( - Controls(code: "remarks", controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: "0"), - ); - controlsProcedure.add(Procedures(category: element.categoryID, procedure: element.procedureId, controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList!.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN!); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getLabs(patient); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getLabs(patient); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast(model.valadteProcedureList[0].entityList![0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - -void addSelectedLabOrder(context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedLabOrder( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedLabOrder extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - - const AddSelectedLabOrder({Key? key, required this.model, required this.patient}) : super(key: key); - @override - _AddSelectedLabOrderState createState() => _AddSelectedLabOrderState(patient: patient, model: model); -} - -class _AddSelectedLabOrderState extends State { - late int selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - _AddSelectedLabOrderState({required this.patient, required this.model}); - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = []; - List entityListProcedure = []; - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - onModelReady: (model) => - model.getProcedureCategory(categoryName: "Laboratory", categoryID: "02", patientId: patient.patientId), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * .90, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 10.0, - ), - if (widget.model.categoriesList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: widget.model.categoriesList[0].entityList!, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => isEntityListSelected(master), - )), - ], - ), - ), - ), - ); - }), - ), - bottomSheet: Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addLabOrder, - fontWeight: FontWeight.w700, - color: Color(0xff359846), - onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast( - TranslationBase.of(context).fillTheMandatoryProcedureDetails, - ); - return; - } - - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, - ), - ], - ), - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList.where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, - {Icon? suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } -} diff --git a/lib/screens/procedures/add_procedure_homeScreen.dart b/lib/screens/procedures/add_procedure_homeScreen.dart deleted file mode 100644 index 8b1a6d2c..00000000 --- a/lib/screens/procedures/add_procedure_homeScreen.dart +++ /dev/null @@ -1,207 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class AddProcedureHome extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - const AddProcedureHome({Key? key, required this.model, required this.patient}) : super(key: key); - @override - _AddProcedureHomeState createState() => _AddProcedureHomeState(patient: patient, model: model); -} - -class _AddProcedureHomeState extends State with SingleTickerProviderStateMixin { - _AddProcedureHomeState({required this.patient, required this.model}); - ProcedureViewModel model; - PatiantInformtion patient; - late TabController _tabController; - int _activeTab = 0; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - _tabController.addListener(_handleTabSelection); - } - - @override - void dispose() { - super.dispose(); - _tabController.dispose(); - } - - _handleTabSelection() { - setState(() { - _activeTab = _tabController.index; - }); - } - - @override - Widget build(BuildContext context) { - //final routeArgs = ModalRoute.of(context).settings.arguments as Map; - //PatiantInformtion patient = routeArgs['patient']; - final screenSize = MediaQuery.of(context).size; - return BaseView( - //onModelReady: (model) => model.getCategory(), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return Container( - height: MediaQuery.of(context).size.height * 1.20, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppText( - 'Add Procedure', - fontWeight: FontWeight.w700, - fontSize: 20, - ), - InkWell( - child: Icon( - Icons.close, - size: 24.0, - ), - onTap: () { - Navigator.pop(context); - }, - ) - ]), - SizedBox( - height: MediaQuery.of(context).size.height * 0.04, - ), - Expanded( - child: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.070), - child: Container( - height: MediaQuery.of(context).size.height * 0.070, - decoration: BoxDecoration( - border: Border( - bottom: - BorderSide(color: Theme.of(context).dividerColor, width: 0.5), //width: 0.7 - ), - color: Colors.white), - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorColor: Colors.transparent, - indicatorWeight: 1.0, - indicatorSize: TabBarIndicatorSize.tab, - labelColor: Theme.of(context).primaryColor, - labelPadding: EdgeInsets.only(top: 0, left: 0, right: 0, bottom: 0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - tabWidget( - screenSize, - _activeTab == 0, - "Favorite Templates", - ), - tabWidget( - screenSize, - _activeTab == 1, - 'All Procedures', - ), - ], - ), - ), - ), - ), - body: Column( - children: [ - Expanded( - child: TabBarView( - physics: BouncingScrollPhysics(), - controller: _tabController, - children: [ - AddFavouriteProcedure( - patient: patient, - model: model, - addButtonTitle: TranslationBase.of(context).addSelectedProcedures!, - toolbarTitle: 'Add Procedure', - ), - AddSelectedProcedure( - model: model, - patient: patient, - ), - ], - ), - ), - ], - ), - ), - ), - ], - ), - ), - ); - }), - ), - ), - ); - } - - Widget tabWidget(Size screenSize, bool isActive, String title, {int counter = -1}) { - return Center( - child: Container( - height: screenSize.height * 0.070, - decoration: TextFieldsUtils.containerBorderDecoration( - isActive ? Color(0xFFD02127 /*B8382B*/) : Color(0xFFEAEAEA), - isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), - borderRadius: 4, - borderWidth: 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - title, - fontSize: SizeConfig.textMultiplier * 1.5, - color: isActive ? Colors.white : Color(0xFF2B353E), - fontWeight: FontWeight.w700, - ), - if (counter != -1) - Container( - margin: EdgeInsets.all(4), - width: 15, - height: 15, - decoration: BoxDecoration( - color: isActive ? Colors.white : Color(0xFFD02127), - shape: BoxShape.circle, - ), - child: Center( - child: FittedBox( - child: AppText( - "$counter", - fontSize: SizeConfig.textMultiplier * 1.5, - color: !isActive ? Colors.white : Color(0xFFD02127), - fontWeight: FontWeight.w700, - ), - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/screens/procedures/add_radiology_order.dart b/lib/screens/procedures/add_radiology_order.dart deleted file mode 100644 index dbd1d774..00000000 --- a/lib/screens/procedures/add_radiology_order.dart +++ /dev/null @@ -1,251 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/enum/viewstate.dart'; -import 'package:doctor_app_flutter/core/model/procedure/ControlsModel.dart'; -import 'package:doctor_app_flutter/core/model/procedure/categories_procedure.dart'; -import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart'; -import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; -import 'package:flutter/material.dart'; - -import 'entity_list_checkbox_search_widget.dart'; - -valdateProcedure(ProcedureViewModel model, PatiantInformtion patient, List entityList) async { - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - - procedureValadteRequestModel.patientMRN = patient.appointmentNo; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; -} - -postProcedure( - {required ProcedureViewModel model, - required String remarks, - String? orderType, - required PatiantInformtion patient, - required List entityList}) async { - PostProcedureReqModel postProcedureReqModel = new PostProcedureReqModel(); - ProcedureValadteRequestModel procedureValadteRequestModel = new ProcedureValadteRequestModel(); - procedureValadteRequestModel.patientMRN = patient.patientMRN; - procedureValadteRequestModel.episodeID = patient.episodeNo; - procedureValadteRequestModel.appointmentNo = patient.appointmentNo; - - List controlsProcedure = []; - - postProcedureReqModel.appointmentNo = patient.appointmentNo; - - postProcedureReqModel.episodeID = patient.episodeNo; - postProcedureReqModel.patientMRN = patient.patientMRN; - - entityList.forEach((element) { - procedureValadteRequestModel.procedure = [element.procedureId!]; - List controls = []; - controls.add( - Controls(code: "remarks", controlValue: element.remarks != null ? element.remarks : ""), - ); - controls.add( - Controls(code: "ordertype", controlValue: "0"), - ); - controlsProcedure.add(Procedures(category: element.categoryID, procedure: element.procedureId, controls: controls)); - }); - - postProcedureReqModel.procedures = controlsProcedure; - await model.valadteProcedure(procedureValadteRequestModel); - if (model.state == ViewState.Idle) { - if (model.valadteProcedureList[0].entityList!.length == 0) { - await model.postProcedure(postProcedureReqModel, patient.patientMRN!); - - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getPatientRadOrders(patient); - } else if (model.state == ViewState.Idle) { - DrAppToastMsg.showSuccesToast('procedure has been added'); - } - } else { - if (model.state == ViewState.ErrorLocal) { - Helpers.showErrorToast(model.error); - model.getPatientRadOrders(patient); - } else if (model.state == ViewState.Idle) { - Helpers.showErrorToast(model.valadteProcedureList[0].entityList![0].warringMessages); - } - } - } else { - Helpers.showErrorToast(model.error); - } -} - -void addSelectedRadiologyOrder(context, ProcedureViewModel model, PatiantInformtion patient) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext bc) { - return AddSelectedRadiologyOrder( - model: model, - patient: patient, - ); - }); -} - -class AddSelectedRadiologyOrder extends StatefulWidget { - final ProcedureViewModel model; - final PatiantInformtion patient; - - const AddSelectedRadiologyOrder({Key? key, required this.model, required this.patient}) : super(key: key); - - @override - _AddSelectedRadiologyOrderState createState() => _AddSelectedRadiologyOrderState(patient: patient, model: model); -} - -class _AddSelectedRadiologyOrderState extends State { - late int selectedType; - ProcedureViewModel model; - PatiantInformtion patient; - - _AddSelectedRadiologyOrderState({required this.patient, required this.model}); - - TextEditingController procedureController = TextEditingController(); - TextEditingController remarksController = TextEditingController(); - List entityList = []; - List entityListProcedure = []; - - dynamic selectedCategory; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - @override - Widget build(BuildContext context) { - final screenSize = MediaQuery.of(context).size; - return BaseView( - onModelReady: (model) => - model.getProcedureCategory(categoryName: "Radiology", categoryID: "03", patientId: patient.patientId), - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( - isShowAppBar: false, - body: NetworkBaseView( - baseViewModel: model, - child: DraggableScrollableSheet( - minChildSize: 0.90, - initialChildSize: 0.95, - maxChildSize: 1.0, - builder: (BuildContext context, ScrollController scrollController) { - return SingleChildScrollView( - child: Container( - height: MediaQuery.of(context).size.height * 1.0, - child: Padding( - padding: EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 10.0, - ), - if (widget.model.categoriesList.length != 0) - NetworkBaseView( - baseViewModel: model, - child: EntityListCheckboxSearchWidget( - model: widget.model, - masterList: widget.model.categoriesList[0].entityList!, - removeHistory: (item) { - setState(() { - entityList.remove(item); - }); - }, - addHistory: (history) { - setState(() { - entityList.add(history); - }); - }, - addSelectedHistories: () { - //TODO build your fun herr - // widget.addSelectedHistories(); - }, - isEntityListSelected: (master) => isEntityListSelected(master), - )), - ], - ), - ), - ), - ); - }), - ), - bottomSheet: Container( - margin: EdgeInsets.all(SizeConfig.widthMultiplier * 5), - child: Wrap( - alignment: WrapAlignment.center, - children: [ - AppButton( - title: TranslationBase.of(context).addRadiologyOrder, - color: Color(0xff359846), - fontWeight: FontWeight.w700, - onPressed: () { - if (entityList.isEmpty == true) { - DrAppToastMsg.showErrorToast(TranslationBase.of(context).fillTheMandatoryProcedureDetails); - return; - } - - Navigator.pop(context); - postProcedure( - orderType: selectedType.toString(), - entityList: entityList, - patient: patient, - model: widget.model, - remarks: remarksController.text); - }, - ), - ], - ), - ), - ), - ); - } - - bool isEntityListSelected(EntityList masterKey) { - Iterable history = entityList.where((element) => masterKey.procedureId == element.procedureId); - if (history.length > 0) { - return true; - } - return false; - } - - InputDecoration textFieldSelectorDecoration(String hintText, String selectedText, bool isDropDown, - {Icon? suffixIcon}) { - return InputDecoration( - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - disabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFCCCCCC), width: 2.0), - borderRadius: BorderRadius.circular(8), - ), - hintText: selectedText != null ? selectedText : hintText, - suffixIcon: isDropDown - ? suffixIcon != null - ? suffixIcon - : Icon( - Icons.arrow_drop_down, - color: Colors.black, - ) - : null, - hintStyle: TextStyle( - fontSize: 14, - color: Colors.grey.shade600, - ), - ); - } -} diff --git a/lib/screens/procedures/add_radiology_screen.dart b/lib/screens/procedures/base_add_procedure_tab_page.dart similarity index 73% rename from lib/screens/procedures/add_radiology_screen.dart rename to lib/screens/procedures/base_add_procedure_tab_page.dart index 63b5f7f5..bdf19051 100644 --- a/lib/screens/procedures/add_radiology_screen.dart +++ b/lib/screens/procedures/base_add_procedure_tab_page.dart @@ -1,33 +1,47 @@ import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-favourite-procedure.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/screens/prescription/add_prescription_form.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/network_base_view.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'add_lab_orders.dart'; -import 'add_radiology_order.dart'; +import 'ProcedureType.dart'; +import 'add-favourite-procedure.dart'; +import 'add-procedure-page.dart'; -class AddRadiologyScreen extends StatefulWidget { +class BaseAddProcedureTabPage extends StatefulWidget { final ProcedureViewModel model; + final PrescriptionViewModel prescriptionModel; final PatiantInformtion patient; - const AddRadiologyScreen({Key? key, required this.model, required this.patient}) : super(key: key); + final ProcedureType procedureType; + + const BaseAddProcedureTabPage( + {Key key, + this.model, + this.prescriptionModel, + this.patient, + @required this.procedureType}) + : super(key: key); + @override - _AddRadiologyScreenState createState() => _AddRadiologyScreenState(patient: patient, model: model); + _BaseAddProcedureTabPageState createState() => _BaseAddProcedureTabPageState( + patient: patient, model: model, procedureType: procedureType); } -class _AddRadiologyScreenState extends State with SingleTickerProviderStateMixin { - _AddRadiologyScreenState({required this.patient, required this.model}); - ProcedureViewModel model; - PatiantInformtion patient; - late TabController _tabController; +class _BaseAddProcedureTabPageState extends State + with SingleTickerProviderStateMixin { + final ProcedureViewModel model; + final PatiantInformtion patient; + final ProcedureType procedureType; + + _BaseAddProcedureTabPageState({this.patient, this.model, this.procedureType}); + + TabController _tabController; int _activeTab = 0; @override @@ -52,8 +66,10 @@ class _AddRadiologyScreenState extends State with SingleTick @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; + return BaseView( - builder: (BuildContext context, ProcedureViewModel model, Widget? child) => AppScaffold( + builder: (BuildContext context, ProcedureViewModel model, Widget child) => + AppScaffold( isShowAppBar: false, body: NetworkBaseView( baseViewModel: model, @@ -63,7 +79,7 @@ class _AddRadiologyScreenState extends State with SingleTick maxChildSize: 1.0, builder: (BuildContext context, ScrollController scrollController) { return Container( - height: MediaQuery.of(context).size.height * 1.20, + height: MediaQuery.of(context).size.height * 1.25, child: Padding( padding: EdgeInsets.all(12.0), child: Column( @@ -71,7 +87,7 @@ class _AddRadiologyScreenState extends State with SingleTick children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppText( - TranslationBase.of(context).addRadiologyOrder, + procedureType.getToolbarLabel(context), fontWeight: FontWeight.w700, fontSize: 20, ), @@ -115,12 +131,13 @@ class _AddRadiologyScreenState extends State with SingleTick tabWidget( screenSize, _activeTab == 0, - "Favorite Templates", + procedureType + .getFavouriteTabName(context), ), tabWidget( screenSize, _activeTab == 1, - 'All Radiology', + procedureType.getAllLabelName(context), ), ], ), @@ -135,16 +152,25 @@ class _AddRadiologyScreenState extends State with SingleTick controller: _tabController, children: [ AddFavouriteProcedure( + model: this.model, + prescriptionModel: + widget.prescriptionModel, patient: patient, - model: model, - addButtonTitle: TranslationBase.of(context).addRadiologyOrder!, - toolbarTitle: TranslationBase.of(context).addRadiologyOrder!, - categoryID: "03", - ), - AddSelectedRadiologyOrder( - model: model, - patient: patient, + procedureType: procedureType, ), + if (widget.procedureType == + ProcedureType.PRESCRIPTION) + PrescriptionFormWidget( + widget.prescriptionModel, + widget.patient, + widget.prescriptionModel + .prescriptionList) + else + AddProcedurePage( + model: this.model, + patient: patient, + procedureType: procedureType, + ), ], ), ), @@ -167,7 +193,7 @@ class _AddRadiologyScreenState extends State with SingleTick child: Container( height: screenSize.height * 0.070, decoration: TextFieldsUtils.containerBorderDecoration( - isActive ? Color(0xFFD02127 /*B8382B*/) : Color(0xFFEAEAEA), + isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), isActive ? Color(0xFFD02127) : Color(0xFFEAEAEA), borderRadius: 4, borderWidth: 0), diff --git a/lib/screens/procedures/entity_list_checkbox_search_widget.dart b/lib/screens/procedures/entity_list_checkbox_search_widget.dart index ea743e6b..a93d8195 100644 --- a/lib/screens/procedures/entity_list_checkbox_search_widget.dart +++ b/lib/screens/procedures/entity_list_checkbox_search_widget.dart @@ -19,6 +19,7 @@ class EntityListCheckboxSearchWidget extends StatefulWidget { final bool Function(EntityList) isEntityListSelected; final List masterList; + /// todo clear the function here EntityListCheckboxSearchWidget( {Key? key, required this.model, diff --git a/lib/screens/procedures/entity_list_fav_procedure.dart b/lib/screens/procedures/entity_list_fav_procedure.dart index 97e3bcba..2172172b 100644 --- a/lib/screens/procedures/entity_list_fav_procedure.dart +++ b/lib/screens/procedures/entity_list_fav_procedure.dart @@ -85,7 +85,7 @@ class _EntityListCheckboxSearchFavProceduresWidgetState extends State masterList; - - ProcedureListWidget( - {Key? key, - required this.model, - required this.addSelectedHistories, - required this.removeHistory, - required this.masterList, - required this.addHistory, - required this.isEntityListSelected, - required this.addRemarks}) - : super(key: key); - - @override - _ProcedureListWidgetState createState() => _ProcedureListWidgetState(); -} - -class _ProcedureListWidgetState extends State { - int selectedType = 0; - late int typeUrgent; - late int typeRegular; - - setSelectedType(int val) { - setState(() { - selectedType = val; - }); - } - - List items = []; - List remarksList = []; - List typeList = []; - - @override - void initState() { - items.addAll(widget.masterList); - super.initState(); - } - - TextEditingController remarksController = TextEditingController(); - @override - Widget build(BuildContext context) { - return Container( - child: Column( - children: [ - NetworkBaseView( - baseViewModel: widget.model, - child: Container( - height: MediaQuery.of(context).size.height * 0.75, - child: Center( - child: Container( - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), - child: ListView( - children: [ - TextFields( - hintText: TranslationBase.of(context).searchProcedures, - suffixIcon: EvaIcons.search, - onChanged: (value) { - filterSearchResults(value); - }, - ), - SizedBox( - height: 15, - ), - items.length != 0 - ? Column( - children: items.map((historyInfo) { - return Column( - children: [ - Row( - children: [ - Checkbox( - value: widget.isEntityListSelected(historyInfo), - activeColor: Colors.red[800], - onChanged: (bool? newValue) { - setState(() { - if (widget.isEntityListSelected(historyInfo)) { - widget.removeHistory(historyInfo); - } else { - widget.addHistory(historyInfo); - } - }); - }), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 0), - child: AppText(historyInfo.procedureName, - variant: "bodyText", bold: true, color: Colors.black), - ), - ), - ], - ), - DividerWithSpacesAround(), - ], - ); - }).toList(), - ) - : Center( - child: Container( - child: AppText("There's no procedures for this category", color: Color(0xFFB9382C)), - ), - ) - ], - ), - )), - ), - ), - SizedBox( - height: 10, - ), - ], - ), - ); - } - - void filterSearchResults(String query) { - List dummySearchList = []; - dummySearchList.addAll(widget.masterList); - if (query.isNotEmpty) { - List dummyListData = []; - dummySearchList.forEach((item) { - if (item.procedureName!.toLowerCase().contains(query.toLowerCase())) { - dummyListData.add(item); - } - }); - setState(() { - items.clear(); - items.addAll(dummyListData); - }); - return; - } else { - setState(() { - items.clear(); - items.addAll(widget.masterList); - }); - } - } -} diff --git a/lib/screens/procedures/procedure_checkout_screen.dart b/lib/screens/procedures/procedure_checkout_screen.dart index aa898411..25864cea 100644 --- a/lib/screens/procedures/procedure_checkout_screen.dart +++ b/lib/screens/procedures/procedure_checkout_screen.dart @@ -4,7 +4,7 @@ import 'package:doctor_app_flutter/core/model/procedure/procedure_template_detai import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add-procedure-form.dart'; +import 'package:doctor_app_flutter/screens/procedures/add-procedure-page.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import '../../widgets/shared/text_fields/TextFields.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; @@ -212,10 +212,9 @@ class _ProcedureCheckOutScreenState extends State { ); }); Navigator.pop(context); - await postProcedure( + await model.preparePostProcedure( entityList: entityList, patient: widget.patient, - model: widget.model, remarks: remarksController.text); Navigator.pop(context); Navigator.pop(context); diff --git a/lib/screens/procedures/procedure_screen.dart b/lib/screens/procedures/procedure_screen.dart index a35f826d..20201360 100644 --- a/lib/screens/procedures/procedure_screen.dart +++ b/lib/screens/procedures/procedure_screen.dart @@ -4,17 +4,18 @@ import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/viewModel/procedure_View_model.dart'; import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/procedures/add_procedure_homeScreen.dart'; import 'package:doctor_app_flutter/screens/procedures/update-procedure.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'ProcedureCard.dart'; +import 'ProcedureType.dart'; +import 'base_add_procedure_tab_page.dart'; class ProcedureScreen extends StatelessWidget { int? doctorNameP; @@ -42,12 +43,8 @@ class ProcedureScreen extends StatelessWidget { isShowAppBar: true, backgroundColor: Colors.grey[100], baseViewModel: model, - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - arrivalType ?? '0', - patientType, - isInpatient: isInpatient, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient:isInpatient,), body: SingleChildScrollView( child: Container( child: Column( @@ -103,10 +100,12 @@ class ProcedureScreen extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => AddProcedureHome( - patient: patient, - model: model, - )), + builder: (context) => BaseAddProcedureTabPage( + patient: patient, + model: model, + procedureType: ProcedureType.PROCEDURE, + ), + ), ); }, child: Container( diff --git a/lib/screens/qr_reader/QR_reader_screen.dart b/lib/screens/qr_reader/QR_reader_screen.dart index e2993767..2ace524a 100644 --- a/lib/screens/qr_reader/QR_reader_screen.dart +++ b/lib/screens/qr_reader/QR_reader_screen.dart @@ -1,11 +1,9 @@ import 'package:barcode_scan_fix/barcode_scan.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/enum/viewstate.dart'; +import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/models/patient/patient_model.dart'; -import 'package:doctor_app_flutter/models/patient/topten_users_res_model.dart'; -import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; +import 'package:doctor_app_flutter/core/viewModel/scan_qr_view_model.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; @@ -26,38 +24,9 @@ class QrReaderScreen extends StatefulWidget { } class _QrReaderScreenState extends State { - DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); - - bool isLoading = false; - bool isError = false; - PatientModel patient = PatientModel( - ProjectID: 15, - ClinicID: 0, - DoctorID: 1485, - FirstName: "0", - MiddleName: "0", - LastName: "0", - PatientMobileNumber: "0", - PatientIdentificationID: "0", - PatientID: 0, - From: "0", - To: "0", - LanguageID: 2, - stamp: "2020-03-02T13:56:39.170Z", - IPAdress: "11.11.11.11", - VersionID: 5.5, - Channel: 9, - TokenID: "@dm!n", - SessionID: "5G0yXn0Jnq", - IsLoginForDoctorApp: true, - PatientOutSA: false); - List patientList = []; - String error = ''; - @override Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getClinicsList(), + return BaseView( builder: (_, model, w) => AppScaffold( baseViewModel: model, isShowAppBar: false, @@ -95,26 +64,8 @@ class _QrReaderScreenState extends State { onPressed: () { _scanQrAndGetPatient(context, model); }, - loading: isLoading, icon: Image.asset('assets/images/qr_code_white.png'), ), - isError - ? Container( - margin: EdgeInsets.only(top: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6.0), - color: Theme.of(context).errorColor.withOpacity(0.06), - ), - padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0), - child: Row( - children: [ - Expanded( - child: AppText(error ?? TranslationBase.of(context).errorMessage, - color: Theme.of(context).errorColor)), - ], - ), - ) - : Container(), ], ), ), @@ -124,82 +75,33 @@ class _QrReaderScreenState extends State { ); } - _scanQrAndGetPatient(BuildContext context, PatientViewModel model) async { + _scanQrAndGetPatient(BuildContext context, ScanQrViewModel model) async { /// When give qr we will change this method to get data /// var result = await BarcodeScanner.scan(); /// int patientID = get from qr result var result = await BarcodeScanner.scan(); if (result != "") { List listOfParams = result.split(','); - String patientType = "1"; - setState(() { - isLoading = true; - isError = false; - patientList = []; - }); - String token = await sharedPref.getString(TOKEN); -// Map profile = await sharedPref.getObj(DOCTOR_PROFILE); -// DoctorProfileModel doctorProfile = new DoctorProfileModel.fromJson(profile); -// patient.PatientID = 8808; -// patient.TokenID = token; -// patient.setDoctorID = doctorProfile.projectID; -// patient.setClinicID = doctorProfile.clinicID; -// patient.setProjectID = doctorProfile.projectID; -// Provider.of(context, listen: false); - patient.PatientID = 8808; - patient.TokenID = token; - model.getPatientList(patient, "1", isBusyLocal: true).then((response) { - if (response['MessageStatus'] == 1) { - switch (patientType) { - case "0": - if (response['List_MyOutPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyOutPatient']).list!; - isLoading = false; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - } - break; - case "1": - if (response['List_MyInPatient'] != null) { - setState(() { - patientList = ModelResponse.fromJson(response['List_MyInPatient']).list!; - isLoading = false; - error = ""; - }); - Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { - "patient": patientList[0], - }); - } else { - setState(() { - isError = true; - isLoading = false; - }); - DrAppToastMsg.showErrorToast('No patient'); - break; - } - } + int patientID = 0; + if (listOfParams[1].length != 0) patientID = int.parse(listOfParams[1]); + PatientSearchRequestModel patientSearchRequestModel = PatientSearchRequestModel( + patientID: patientID, + ); + + await model.getInPatientList(patientSearchRequestModel, isMyInpatient: true).then((d) { + if (model.state != ViewState.ErrorLocal) { + if (model.inPatientList.isEmpty) + DrAppToastMsg.showErrorToast('No patient'); + else + Navigator.of(context).pushNamed(PATIENTS_PROFILE, arguments: { + "patient": model.inPatientList[0], + }); } else { - setState(() { - isLoading = false; - isError = true; - }); - DrAppToastMsg.showErrorToast(response['ErrorEndUserMessage'] ?? response['ErrorMessage']); + + DrAppToastMsg.showErrorToast(model.error); } }).catchError((error) { - setState(() { - isLoading = false; - }); Helpers.showErrorToast(error.message); - //DrAppToastMsg.showErrorToast(error); }); } } diff --git a/lib/screens/sick-leave/add-sickleave.dart b/lib/screens/sick-leave/add-sickleave.dart index 0fdef251..f39f50ea 100644 --- a/lib/screens/sick-leave/add-sickleave.dart +++ b/lib/screens/sick-leave/add-sickleave.dart @@ -1,15 +1,14 @@ import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/model/sick_leave/sick_leave_patient_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; - import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/models/sickleave/get_all_sickleave_response.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/screens/sick-leave/sick_leave.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; @@ -33,12 +32,8 @@ class AddSickLeavScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", - isInpatient: isInpatient, - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient: patient, isInpatient:isInpatient,), body: SingleChildScrollView( child: Column(children: [ patient.patientStatusType == 43 diff --git a/lib/screens/sick-leave/show-sickleave.dart b/lib/screens/sick-leave/show-sickleave.dart index b97fe553..3f0eb82f 100644 --- a/lib/screens/sick-leave/show-sickleave.dart +++ b/lib/screens/sick-leave/show-sickleave.dart @@ -1,11 +1,11 @@ import 'package:doctor_app_flutter/core/viewModel/sick_leave_view_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/models/sickleave/get_all_sickleave_response.dart'; import 'package:doctor_app_flutter/screens/base/base_view.dart'; import 'package:doctor_app_flutter/util/date-utils.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; @@ -24,11 +24,8 @@ class ShowSickLeaveScreen extends StatelessWidget { baseViewModel: model, isShowAppBar: true, backgroundColor: Colors.grey[100], - appBar: PatientProfileHeaderNewDesignAppBar( - patient, - routeArgs['patientType'] ?? "0", - routeArgs['arrivalType'] ?? "0", - ), + patientProfileAppBarModel: PatientProfileAppBarModel( + patient:patient), body: SingleChildScrollView( child: Column( children: [ diff --git a/lib/util/NotificationPermissionUtils.dart b/lib/util/NotificationPermissionUtils.dart new file mode 100644 index 00000000..8950fae3 --- /dev/null +++ b/lib/util/NotificationPermissionUtils.dart @@ -0,0 +1,42 @@ +import 'package:doctor_app_flutter/widgets/dialog/AskPermissionDialog.dart'; +import 'package:doctor_app_flutter/widgets/transitions/slide_up_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +class AppPermissionsUtils { + + static requestVideoCallPermission({BuildContext context, String type,Function onTapGrant}) async { + + var cameraPermission = Permission.camera; + var microphonePermission = Permission.microphone; + PermissionStatus permissionCameraStatus = await cameraPermission.status; + PermissionStatus permissionMicrophoneStatus = await microphonePermission.status; + + if (permissionCameraStatus.isPermanentlyDenied || permissionMicrophoneStatus.isPermanentlyDenied) { + await _showPermissionDialog(context, type,onTapGrant); + } else if (!permissionCameraStatus.isGranted || !permissionMicrophoneStatus.isGranted) { + permissionCameraStatus = await cameraPermission.request(); + permissionMicrophoneStatus = await microphonePermission.request(); + if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } else if (permissionCameraStatus.isDenied || permissionMicrophoneStatus.isDenied) + await _showPermissionDialog(context, type,onTapGrant); + else + onTapGrant(); + } + + static _showPermissionDialog(BuildContext context, String type,Function onTapGrant) async { + Navigator.push( + context, SlideUpPageRoute(widget: AskPermissionDialog(type: type,onTapGrant: onTapGrant,))); + } + + static Future isVideoCallPermissionGranted() async { + PermissionStatus permissionCameraStatus = await Permission.camera.status; + PermissionStatus permissionMicrophoneStatus = await Permission.microphone.status; + return permissionCameraStatus.isGranted && permissionMicrophoneStatus.isGranted; + } +} diff --git a/lib/util/VideoChannel.dart b/lib/util/VideoChannel.dart index c0bd4e87..dc60efaf 100644 --- a/lib/util/VideoChannel.dart +++ b/lib/util/VideoChannel.dart @@ -3,6 +3,7 @@ import 'dart:io' show Platform; import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/models/livecare/session_status_model.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class VideoChannel { @@ -18,11 +19,24 @@ class VideoChannel { String? tokenID, String? generalId, int? doctorId, - Function()? onCallEnd, + String patientName, Function()? onCallEnd, Function(SessionStatusModel sessionStatusModel)? onCallNotRespond, - Function(String error)? onFailure}) async { + Function(String error)? onFailure, VoidCallback onCallConnected, VoidCallback onCallDisconnected}) async { + + onCallConnected = onCallConnected ?? (){}; + onCallDisconnected = onCallDisconnected ?? (){}; var result; try { + _channel.setMethodCallHandler((call) { + if(call.method == 'onCallConnected'){ + onCallConnected(); + } + if(call.method == 'onCallDisconnected'){ + onCallDisconnected(); + } + return true as dynamic; + }); + result = await _channel.invokeMethod( 'openVideoCall', { @@ -35,6 +49,7 @@ class VideoChannel { "TokenID": tokenID, "generalId": generalId, "DoctorId": doctorId, + "patientName": patientName, }, ); if (result['callResponse'] == 'CallEnd') { diff --git a/lib/util/date-utils.dart b/lib/util/date-utils.dart index 9ce078ed..9b00ba2b 100644 --- a/lib/util/date-utils.dart +++ b/lib/util/date-utils.dart @@ -16,7 +16,11 @@ class AppDateUtils { } static String convertStringToDateFormat(String date, String dateFormat) { - DateTime dateTime = DateTime.parse(date); + DateTime dateTime ; + if(date.contains("/Date")) + dateTime= getDateTimeFromServerFormat(date); + else + dateTime = DateTime.parse(date); return convertDateToFormat(dateTime, dateFormat); } @@ -68,20 +72,26 @@ class AppDateUtils { return "$days ${TranslationBase.of(context).days}, $months ${TranslationBase.of(context).months}, $years ${TranslationBase.of(context).years}"; } - static String differenceBetweenDateAndCurrent(DateTime firstDate, BuildContext context) { + static String differenceBetweenDateAndCurrent(DateTime firstDate, BuildContext context, {bool isShowSecond = false, bool isShowDays = true }) { DateTime now = DateTime.now(); - // DateTime now = nows.add(Duration(days: 400, minutes: 25, hours: 0)); var difference = now.difference(firstDate); int minutesInDays = difference.inMinutes; + int secondInDays = difference.inSeconds; int hoursInDays = minutesInDays ~/ 60; // ~/ : truncating division to make the result int + int second = secondInDays % 60; int minutes = minutesInDays % 60; int days = hoursInDays ~/ 24; int hours = hoursInDays % 24; double hoursInOneDay = difference.inHours / difference.inDays; - return "$days ${TranslationBase.of(context).days}, $hours ${TranslationBase.of(context).hr}, $minutes ${TranslationBase.of(context).min}"; + return (isShowDays + ? (days > 0 ? "$days ${TranslationBase.of(context).days}," : '') + : "") + + (hours > 0 ? "$hours ${TranslationBase.of(context).hr}," : "") + + " $minutes ${TranslationBase.of(context).min}" + + (isShowSecond ? ", $second Sec" : ""); } static String differenceBetweenServerDateAndCurrent(String str, BuildContext context) { @@ -365,4 +375,44 @@ class AppDateUtils { else return ""; } + + + // handel date like "09/05/2021 17:00" + static DateTime getDateTimeFromString(String str) { + List array = str.split('/'); + int day = int.parse(array[0]); + int month = int.parse(array[1]); + + List array2 = array[2].split(' '); + int year = int.parse(array2[0]); + String hour = array2[1]; + List hourList = hour.split(":"); + + DateTime date = DateTime(year, month, day, int.parse(hourList[0]), int.parse(hourList[1])); + + + return date; + } + + + static convertDateFormatImproved(String str) { + String newDate; + const start = "/Date("; + if (str.isNotEmpty) { + const end = "+0300)"; + + final startIndex = str.indexOf(start); + final endIndex = str.indexOf(end, startIndex + start.length); + + var date = new DateTime.fromMillisecondsSinceEpoch( + int.parse(str.substring(startIndex + start.length, endIndex))); + newDate = date.year.toString() + + "/" + + date.month.toString().padLeft(2, '0') + + "/" + + date.day.toString().padLeft(2, '0'); + } + + return newDate??''; + } } diff --git a/lib/util/helpers.dart b/lib/util/helpers.dart index a9da05d1..2376e191 100644 --- a/lib/util/helpers.dart +++ b/lib/util/helpers.dart @@ -1,11 +1,8 @@ import 'package:connectivity/connectivity.dart'; import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/core/model/hospitals/get_hospitals_response_model.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/models/doctor/list_doctor_working_hours_table_model.dart'; -import 'package:doctor_app_flutter/screens/auth/login_screen.dart'; import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; @@ -258,4 +255,26 @@ class Helpers { var htmlRegex = RegExp("<(“[^”]*”|'[^’]*’|[^'”>])*>"); return htmlRegex.hasMatch(text); } + + static getNameFromKPI(String kpi) { + if (kpi.indexOf("(") > -1) + return kpi.substring(0, kpi.indexOf("(")); + else + return kpi; + } + + static getLabelFromKPI(String kpi) { + if (kpi.indexOf("(") > -1 && kpi.indexOf(")")>-1) + return kpi.substring(kpi.indexOf("(") + 1, kpi.indexOf(")")); + else + return ''; + + } + + static String timeFrom({Duration duration}) { + String twoDigits(int n) => n.toString().padLeft(2, "0"); + String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); + String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); + return "$twoDigitMinutes:$twoDigitSeconds"; + } } diff --git a/lib/util/translations_delegate_base.dart b/lib/util/translations_delegate_base.dart index 28feb82e..270b4ad3 100644 --- a/lib/util/translations_delegate_base.dart +++ b/lib/util/translations_delegate_base.dart @@ -847,6 +847,8 @@ class TranslationBase { String? get selectProcedures => localizedValues['selectProcedures']![locale.languageCode]; String? get addSelectedProcedures => localizedValues['addSelectedProcedures']![locale.languageCode]; + String get addProcedures => + localizedValues['addProcedures'][locale.languageCode]; String? get updateProcedure => localizedValues['updateProcedure']![locale.languageCode]; @@ -1079,6 +1081,14 @@ class TranslationBase { String? get impressionRecommendation => localizedValues['impressionRecommendation']![locale.languageCode]; String? get onHold => localizedValues['onHold']![locale.languageCode]; String? get verified => localizedValues['verified']![locale.languageCode]; + String get favoriteTemplates => localizedValues['favoriteTemplates'][locale.languageCode]; + String get allProcedures => localizedValues['allProcedures'][locale.languageCode]; + String get allRadiology => localizedValues['allRadiology'][locale.languageCode]; + String get allLab => localizedValues['allLab'][locale.languageCode]; + String get allPrescription => localizedValues['allPrescription'][locale.languageCode]; + String get addPrescription => localizedValues['addPrescription'][locale.languageCode]; + String get edit => localizedValues['edit'][locale.languageCode]; + String get summeryReply => localizedValues['summeryReply'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/auth/method_type_card.dart b/lib/widgets/auth/method_type_card.dart index a43d37e9..08c0b193 100644 --- a/lib/widgets/auth/method_type_card.dart +++ b/lib/widgets/auth/method_type_card.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -17,6 +18,7 @@ class MethodTypeCard extends StatelessWidget { @override Widget build(BuildContext context) { + double cardHeight = SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort? 22 : SizeConfig.isHeightLarge?25:20); return InkWell( onTap: onTap, child: Container( @@ -28,30 +30,26 @@ class MethodTypeCard extends StatelessWidget { ), border: Border.all(color: HexColor('#707070'), width: 0.1), ), - height: 170, - child: Padding( - padding: EdgeInsets.fromLTRB(20, 15, 20, 15), + height: cardHeight, + child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Image.asset( - assetPath, - height: 60, - width: 60, - ), - ], + Image.asset( + assetPath, + width: SizeConfig.widthMultiplier* (12), + height: cardHeight * 0.35, + // height: , ), SizedBox( height: height, ), AppText( label, - fontSize: 14, - color: Color(0xFF2E303A), - fontWeight: FontWeight.bold, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth()* (SizeConfig.isHeightVeryShort?3:3.7), + color: Color(0xFF2B353E), + fontWeight: FontWeight.w700, ) ], ), diff --git a/lib/widgets/auth/sms-popup.dart b/lib/widgets/auth/sms-popup.dart index ca8f8075..91838dbd 100644 --- a/lib/widgets/auth/sms-popup.dart +++ b/lib/widgets/auth/sms-popup.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/enum/auth_method_types.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; @@ -49,84 +48,88 @@ class SMSOTP { late String displayTime = ''; late bool isClosed = false; displayDialog(BuildContext context) async { + double dialogWidth = MediaQuery.of(context).size.width * 0.90; + double dialogInputWidth = (dialogWidth / 4) - (SizeConfig.isWidthLarge?SizeConfig.getWidthMultiplier(width:dialogWidth )* 4.5: 20); + double dialogHeight = SizeConfig.isHeightVeryShort ?MediaQuery.of(context).size.height * 0.50:MediaQuery.of(context).size.height * 0.40; return showDialog( context: context, - barrierColor: Colors.black.withOpacity(0.7), - builder: (context) { - projectProvider = Provider.of(context); - return AlertDialog( - contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 0.0, 24.0), - content: StatefulBuilder(builder: (context, setState) { - if (displayTime == '') { - startTimer(setState); - } - return Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.50, - width: MediaQuery.of(context).size.width * 0.84, + + + builder: (ctx) => Center( + child: Container( + color: Colors.white, + height: dialogHeight, + width: dialogWidth, + child: Material( + color: Colors.white, + child: SingleChildScrollView( child: Center( - child: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(13), - child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - type == AuthMethodTypes.SMS - ? Padding( - child: Icon( - DoctorApp.verify_sms_1, - size: 50, - ), - padding: EdgeInsets.only(bottom: 20), - ) - : Padding( - child: Icon( + child: Container( + color: Colors.white, + child: StatefulBuilder(builder: (context, setState) { + if (displayTime == '') { + startTimer(setState); + } + + return Center( + child: FractionallySizedBox( + widthFactor: 0.9, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: SizeConfig.getHeightMultiplier(height:dialogHeight) * 2,), + + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Icon(type == AuthMethodTypes.SMS + ? + DoctorApp.verify_sms_1 + : DoctorApp.verify_whtsapp, - size: 50, - ), - padding: EdgeInsets.only(bottom: 20), + size: SizeConfig.getHeightMultiplier(height:dialogHeight) * 9, + color: Color(0xFF2B353E), ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Padding( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 20), - child: IconButton( - icon: Icon(Icons.close), - iconSize: 40, + IconButton( + icon: Icon(Icons.close),color: Color(0xFF2B353E), + iconSize: SizeConfig.getHeightMultiplier(height:dialogHeight) * 15, onPressed: () { this.isClosed = true; Navigator.pop(context); this.onFailure(); }, - )) + ) ], ) - ])), - Padding( - padding: EdgeInsets.only(top: 5, right: 5), - child: AppText( - TranslationBase.of(context).verificationMessage! + + ]), + SizedBox(height: SizeConfig.getHeightMultiplier(height:dialogHeight) * (SizeConfig.isHeightVeryShort?10:5),), + Padding( + padding: EdgeInsets.only(top: 5, right: 5), + child: AppText( + TranslationBase.of(context).verificationMessage! + ' XXXXXX' + mobileNo.toString().substring(mobileNo.toString().length - 3), textAlign: TextAlign.start, - fontWeight: FontWeight.bold, - fontSize: 14, - maxLines: 2, - )), - Form( - key: verifyAccountForm, - child: Padding( - padding: EdgeInsets.only(top: 20), - child: Directionality( - textDirection: TextDirection.ltr, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - width: SizeConfig.realScreenWidth * 0.16, - margin: EdgeInsets.all(5), + fontWeight: FontWeight.w700, + letterSpacing: -0.48, + color: Color(0xFF2B353E), + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: dialogWidth) * 3.5, //14, + maxLines: 2, + )), + Form( + key: verifyAccountForm, + child: Padding( + padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier(height:dialogHeight) * 2), + child: Directionality( + textDirection: TextDirection.ltr, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + width: dialogInputWidth, + height: SizeConfig.getHeightMultiplier(height:dialogHeight) * 30, + margin: EdgeInsets.symmetric(vertical: 2,horizontal:5), child: TextFormField( textInputAction: TextInputAction.next, style: buildTextStyle(), @@ -151,8 +154,10 @@ class SMSOTP { ), ), Container( - width: SizeConfig.realScreenWidth * 0.16, - margin: EdgeInsets.all(5), + width: dialogInputWidth, + height: SizeConfig.getHeightMultiplier(height:dialogHeight) * 30, + + margin: EdgeInsets.symmetric(vertical: 2,horizontal:5), child: TextFormField( focusNode: focusD2, textInputAction: TextInputAction.next, @@ -176,8 +181,9 @@ class SMSOTP { validator: validateCodeDigit), ), Container( - margin: EdgeInsets.all(5), - width: SizeConfig.realScreenWidth * 0.16, + margin: EdgeInsets.symmetric(vertical: 2,horizontal: 5), + width: dialogInputWidth, + height: SizeConfig.getHeightMultiplier(height:dialogHeight) * 30, child: TextFormField( focusNode: focusD3, textInputAction: TextInputAction.next, @@ -200,8 +206,9 @@ class SMSOTP { }, validator: validateCodeDigit)), Container( - margin: EdgeInsets.all(5), - width: SizeConfig.realScreenWidth * 0.16, + margin: EdgeInsets.symmetric(vertical: 2,horizontal: 5), + width: dialogInputWidth, + height: SizeConfig.getHeightMultiplier(height:dialogHeight) * 30, child: TextFormField( focusNode: focusD4, maxLength: 1, @@ -224,37 +231,46 @@ class SMSOTP { )), ), ), - Padding( - padding: const EdgeInsets.all(12.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).validationMessage! + ' ', - fontWeight: FontWeight.w600, - fontSize: 14, + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).validationMessage! + ' ',textAlign: TextAlign.start, + fontWeight: FontWeight.w700, + letterSpacing: -0.48, + color: Color(0xFF2B353E), + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: dialogWidth) * 3.5, + ), + AppText( + displayTime, + color: Colors.red, + textAlign: TextAlign.start, + fontWeight: FontWeight.bold, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: dialogWidth) * 3.5, + ) + ]) + ], ), - AppText( - displayTime, - color: Colors.red, - textAlign: TextAlign.start, - fontWeight: FontWeight.bold, - fontSize: 14, - ) - ]), - ) - ], - ))), - ); - }), - ); - }); + ), + ); + + }) + + + ), + ), + ), + ), + ), + ), + + ); } TextStyle buildTextStyle() { return TextStyle( - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier * 2.5, ); } diff --git a/lib/widgets/auth/verification_methods_list.dart b/lib/widgets/auth/verification_methods_list.dart index 8d69edd3..0e7a61c7 100644 --- a/lib/widgets/auth/verification_methods_list.dart +++ b/lib/widgets/auth/verification_methods_list.dart @@ -38,14 +38,14 @@ class _VerificationMethodsListState extends State { return MethodTypeCard( assetPath: 'assets/images/verify-whtsapp.png', onTap: () => {widget.authenticateUser!(AuthMethodTypes.WhatsApp, true)}, - label: TranslationBase.of(context).verifyWith ?? "" + TranslationBase.of(context).verifyWhatsApp!, + label: TranslationBase.of(context).verifyWith ?? "" +"\n"+ TranslationBase.of(context).verifyWhatsApp!, ); break; case AuthMethodTypes.SMS: return MethodTypeCard( assetPath: "assets/images/verify-sms.png", onTap: () => {widget.authenticateUser!(AuthMethodTypes.SMS, true)}, - label: TranslationBase.of(context).verifyWith ?? "" + TranslationBase.of(context).verifySMS!, + label: TranslationBase.of(context).verifyWith ?? "" + "\n"+ TranslationBase.of(context).verifySMS!, ); break; case AuthMethodTypes.Fingerprint: @@ -56,7 +56,7 @@ class _VerificationMethodsListState extends State { widget.authenticateUser!(AuthMethodTypes.Fingerprint, true); } }, - label: TranslationBase.of(context).verifyWith ?? "" + TranslationBase.of(context).verifyFingerprint!, + label: TranslationBase.of(context).verifyWith ?? "" + "\n"+TranslationBase.of(context).verifyFingerprint!, ); break; case AuthMethodTypes.FaceID: @@ -67,7 +67,7 @@ class _VerificationMethodsListState extends State { widget.authenticateUser!(AuthMethodTypes.FaceID, true); } }, - label: TranslationBase.of(context).verifyWith ?? "" + TranslationBase.of(context).verifyFaceID!, + label: TranslationBase.of(context).verifyWith ?? "" + "\n"+TranslationBase.of(context).verifyFaceID!, ); break; @@ -76,7 +76,7 @@ class _VerificationMethodsListState extends State { assetPath: 'assets/images/login/more_icon.png', onTap: widget.onShowMore!, label: TranslationBase.of(context).moreVerification!, - height: 0, + // height: 40, ); } } diff --git a/lib/widgets/dashboard/activity_button.dart b/lib/widgets/dashboard/activity_button.dart deleted file mode 100644 index ff9db962..00000000 --- a/lib/widgets/dashboard/activity_button.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; - -class GetActivityButton extends StatelessWidget { - final value; - - GetActivityButton(this.value); - - @override - Widget build(BuildContext context) { - return Container( - width: MediaQuery.of(context).size.height * 0.125, - padding: EdgeInsets.all(5), - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - ), - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AppText( - value.value.toString(), - fontSize: 27, - fontWeight: FontWeight.bold, - color: Color(0xFF2B353E), - ), - AppText( - value.kPIParameter, - textOverflow: TextOverflow.clip, - fontSize: 10, - color: Color(0xFF2B353E), - textAlign: TextAlign.start, - fontWeight: FontWeight.w700, - ), - ], - ), - ), - ); - } -} diff --git a/lib/widgets/dashboard/activity_card.dart b/lib/widgets/dashboard/activity_card.dart new file mode 100644 index 00000000..30e889f8 --- /dev/null +++ b/lib/widgets/dashboard/activity_card.dart @@ -0,0 +1,50 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class GetActivityCard extends StatelessWidget { + final value; + + GetActivityCard(this.value); + + @override + Widget build(BuildContext context) { + double width = SizeConfig.heightMultiplier* (SizeConfig.isHeightVeryShort?16:SizeConfig.isHeightShort?14:SizeConfig.isHeightLarge?15:13); + return Container( + width: width, + padding: EdgeInsets.symmetric(horizontal: SizeConfig.heightMultiplier * .4, vertical: SizeConfig.heightMultiplier * .2), + margin: EdgeInsets.all(SizeConfig.widthMultiplier *1), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(8,8, 8, 4), + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + value.value.toString(), + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: width)* 25, + fontWeight: FontWeight.bold, + color: Color(0xFF2B353E), + letterSpacing: -0.93, + ), + AppText( + value.kPIParameter, + textOverflow: TextOverflow.clip, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: width)* (SizeConfig.isHeightVeryShort?8: SizeConfig.isHeightShort?8: 9), + color: Color(0xFF2B353E), + textAlign: TextAlign.start, + fontWeight: FontWeight.w700, + letterSpacing: -0.33, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/dashboard/out_patient_stack.dart b/lib/widgets/dashboard/out_patient_stack.dart index bd9722e3..049f3fd8 100644 --- a/lib/widgets/dashboard/out_patient_stack.dart +++ b/lib/widgets/dashboard/out_patient_stack.dart @@ -1,4 +1,7 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart'; +import 'package:doctor_app_flutter/screens/home/label.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; @@ -9,20 +12,37 @@ class GetOutPatientStack extends StatelessWidget { @override Widget build(BuildContext context) { + double barHeight = + SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort ? 20 : SizeConfig.isHeightLarge?20:17); value.summaryoptions.sort((Summaryoptions a, Summaryoptions b) => b.value! - a.value!); var list = []; - value.summaryoptions.forEach((result) => {list.add(getStack(result, value.summaryoptions.first.value, context))}); + value.summaryoptions.forEach((result) => {list.add(getStack(result, value.summaryoptions.first.value, context, barHeight)) + }); return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( - height: 30, - child: AppText( - value.kPIName, - medium: true, - fontSize: 14, + padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5), + child: Label( + firstLine: Helpers.getLabelFromKPI(value.kPIName), + secondLine: Helpers.getNameFromKPI(value.kPIName), + color: Color(0xFF2B353E), + firstLineFontSize: + SizeConfig.getHeightMultiplier(height: barHeight) * + (SizeConfig.isHeightVeryShort + ? 10 + : SizeConfig.isHeightShort + ? 10 + : 8.5), + secondLineFontSize: + SizeConfig.getHeightMultiplier(height: barHeight) * + (SizeConfig.isHeightVeryShort + ? 15 + : SizeConfig.isHeightShort + ? 15 + : 14.5), ), ), Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: list) @@ -30,7 +50,7 @@ class GetOutPatientStack extends StatelessWidget { ); } - getStack(Summaryoptions value, max, context) { + getStack(Summaryoptions value, max, context, barHeight) { return Expanded( child: Container( margin: EdgeInsets.symmetric(horizontal: 2), @@ -41,7 +61,7 @@ class GetOutPatientStack extends StatelessWidget { colors: [Color(0x8FF5F6FA), Colors.red[50]!], // red to yellow tileMode: TileMode.mirror, // repeats the gradient over the canvas ), - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(4), // color: Colors.red[50], ), child: Stack(children: [ @@ -52,15 +72,15 @@ class GetOutPatientStack extends StatelessWidget { child: Container( child: SizedBox(), padding: EdgeInsets.all(10), - height: max != 0 ? ((MediaQuery.of(context).size.height * 0.24) * value.value!) / max : 0, + height: max != 0 ? ((barHeight) * value.value!) / max : 0, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(4), color: Color(0x63D02127), ), ), ), Container( - height: (MediaQuery.of(context).size.height * 0.24), + height: barHeight, margin: EdgeInsets.only(left: 5, top: 5), padding: EdgeInsets.all(10), child: RotatedBox( @@ -72,16 +92,18 @@ class GetOutPatientStack extends StatelessWidget { children: [ AppText( value.kPIParameter, - fontSize: 10, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 2.5, textAlign: TextAlign.center, color: Color(0xFF2B353E), fontWeight: FontWeight.w700, + letterSpacing: -0.3, ), AppText( ' (' + value.value.toString() + ') ', - fontSize: 12, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 2.5, textAlign: TextAlign.center, color: Color(0xFF2B353E), + letterSpacing: -0.3, fontWeight: FontWeight.bold, ), ], @@ -93,4 +115,5 @@ class GetOutPatientStack extends StatelessWidget { ), ); } + } diff --git a/lib/widgets/dashboard/row_count.dart b/lib/widgets/dashboard/row_count.dart index a22932f4..dcadb8be 100644 --- a/lib/widgets/dashboard/row_count.dart +++ b/lib/widgets/dashboard/row_count.dart @@ -1,15 +1,17 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:flutter/material.dart'; class RowCounts extends StatelessWidget { final name; final int count; + final double height; final Color c; - RowCounts(this.name, this.count, this.c); + RowCounts(this.name, this.count, this.c, {this.height}); @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.only(top: 5, bottom: 5), + padding: EdgeInsets.only(top:SizeConfig.getHeightMultiplier(height:height )* 0.2 , bottom: SizeConfig.getHeightMultiplier(height:height )* 0.2), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -24,7 +26,7 @@ class RowCounts extends StatelessWidget { name, color: Colors.black, textAlign: TextAlign.start, // from TextAlign.center - fontSize: 11, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 2.5, textOverflow: TextOverflow.ellipsis, ), ), @@ -32,7 +34,7 @@ class RowCounts extends StatelessWidget { ' (' + count.toString() + ')', color: Colors.black, textAlign: TextAlign.center, - fontSize: 12, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 3, fontWeight: FontWeight.bold, ) ], @@ -45,8 +47,8 @@ class RowCounts extends StatelessWidget { Widget dot(Color c) { return Container( - padding: EdgeInsets.all(5.0), - margin: EdgeInsets.all(5.0), + padding: EdgeInsets.all(SizeConfig.getHeightMultiplier(height:height )* 2), + margin: EdgeInsets.all(SizeConfig.getHeightMultiplier(height:height )* 1), decoration: BoxDecoration(color: c, shape: BoxShape.circle)); } } diff --git a/lib/widgets/dashboard/swiper_rounded_pagination.dart b/lib/widgets/dashboard/swiper_rounded_pagination.dart index 7e5c2c70..c0360d96 100644 --- a/lib/widgets/dashboard/swiper_rounded_pagination.dart +++ b/lib/widgets/dashboard/swiper_rounded_pagination.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:flutter/material.dart'; class SwiperRoundedPagination extends StatelessWidget { @@ -7,15 +8,14 @@ class SwiperRoundedPagination extends StatelessWidget { Widget build(BuildContext context) { return active == true ? Container( - height: 5, - width: 30, - // margin: EdgeInsets.only(10), + height: SizeConfig.heightMultiplier * .6, + width: SizeConfig.widthMultiplier * 6, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: Colors.black), ) : Container( - height: 5, - width: 8, + height: SizeConfig.heightMultiplier * .6, + width: SizeConfig.widthMultiplier * 2, margin: EdgeInsets.all(2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey)); diff --git a/lib/widgets/dialog/AskPermissionDialog.dart b/lib/widgets/dialog/AskPermissionDialog.dart new file mode 100644 index 00000000..58718373 --- /dev/null +++ b/lib/widgets/dialog/AskPermissionDialog.dart @@ -0,0 +1,90 @@ +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; +import 'package:doctor_app_flutter/widgets/shared/buttons/secondary_button.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; + +class AskPermissionDialog extends StatefulWidget { + final String type; + final Function onTapGrant; + + AskPermissionDialog({this.type, this.onTapGrant}); + + @override + _AskPermissionDialogState createState() => _AskPermissionDialogState(); +} + +class _AskPermissionDialogState extends State { + getText() { + return "Turn on your Camera, Microphone to start video call"; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + automaticallyImplyLeading: false, + elevation: 0.5, + actions: [ + Padding( + padding: EdgeInsets.only(right: 18.0), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: Feedback.wrapForTap(() { + Navigator.pop(context); + }, context), + child: + Icon(EvaIcons.close, color: Theme.of(context).primaryColor), + ), + ) + ], + ), + body: Container( + margin: EdgeInsets.symmetric(horizontal: 48), + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AppText( + "🙋‍♀", + style: "headline1", + color: Colors.black, + ), + AppText( + "Don't miss out!", + style: "headline4", + color: Colors.black, + ), + SizedBox( + height: 8, + ), + AppText( + getText(), + color: Colors.grey, + style: "bodyText2", + textAlign: TextAlign.center, + ), + SizedBox( + height: MediaQuery.of(context).size.height / 6, + ), + AppButton( + fontColor: Theme.of(context).backgroundColor, + color: Colors.red[700], + title: "Turn On Camera, Microphone", + onPressed: () async { + openAppSettings().then((value) { + Navigator.pop(context); + widget.onTapGrant(); + }); + }, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/patients/patient-referral-item-widget.dart b/lib/widgets/patients/patient-referral-item-widget.dart index 6209e1fc..337f630e 100644 --- a/lib/widgets/patients/patient-referral-item-widget.dart +++ b/lib/widgets/patients/patient-referral-item-widget.dart @@ -60,7 +60,7 @@ class PatientReferralItemWidget extends StatelessWidget { child: CardWithBgWidget( bgColor: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 + : referralStatusCode == 46 || referralStatusCode == 2 ? Colors.green[700]! : Colors.red[700]!, hasBorder: false, @@ -80,7 +80,7 @@ class PatientReferralItemWidget extends StatelessWidget { fontWeight: FontWeight.w700, color: referralStatusCode == 1 ? Color(0xffc4aa54) - : referralStatusCode == 46 + : referralStatusCode == 46 || referralStatusCode == 2 ? Colors.green[700] : Colors.red[700], ), @@ -157,6 +157,7 @@ class PatientReferralItemWidget extends StatelessWidget { ), Row( mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText( isSameBranch @@ -167,16 +168,18 @@ class PatientReferralItemWidget extends StatelessWidget { fontSize: 1.7 * SizeConfig.textMultiplier!, color: Color(0XFF575757), ), - AppText( - !isReferralClinic! + Expanded( + child: AppText( + !isReferralClinic! ? isSameBranch ? TranslationBase.of(context).sameBranch : TranslationBase.of(context).otherBranch : " " + referralClinic!, - fontFamily: 'Poppins', - fontWeight: FontWeight.w700, - fontSize: 1.8 * SizeConfig.textMultiplier, - color: Color(0XFF2E303A), + fontFamily: 'Poppins', + fontWeight: FontWeight.w700, + fontSize: 1.8 * SizeConfig.textMultiplier, + color: Color(0XFF2E303A), + ), ), ], ), diff --git a/lib/widgets/patients/PatientCard.dart b/lib/widgets/patients/patient_card/PatientCard.dart similarity index 99% rename from lib/widgets/patients/PatientCard.dart rename to lib/widgets/patients/patient_card/PatientCard.dart index 1ff05222..beffc92f 100644 --- a/lib/widgets/patients/PatientCard.dart +++ b/lib/widgets/patients/patient_card/PatientCard.dart @@ -9,6 +9,8 @@ import 'package:doctor_app_flutter/widgets/shared/card_with_bg_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'ShowTimer.dart'; + class PatientCard extends StatelessWidget { final PatiantInformtion patientInfo; final GestureTapCallback onTap; @@ -19,7 +21,7 @@ class PatientCard extends StatelessWidget { final bool isFromSearch; final bool isFromLiveCare; - const PatientCard( + PatientCard( {Key? key, required this.patientInfo, required this.onTap, @@ -33,6 +35,7 @@ class PatientCard extends StatelessWidget { @override Widget build(BuildContext context) { + return Container( width: SizeConfig.screenWidth * 0.9, margin: EdgeInsets.all(6), @@ -239,6 +242,7 @@ class PatientCard extends StatelessWidget { textOverflow: TextOverflow.ellipsis, ), ), + if (patientInfo.gender == 1) Icon( DoctorApp.male_2, @@ -249,6 +253,9 @@ class PatientCard extends StatelessWidget { DoctorApp.female_1, color: Colors.pink, ), + + if(isFromLiveCare) + ShowTimer(patientInfo: patientInfo,), ]), ), Row( @@ -455,4 +462,6 @@ class PatientCard extends StatelessWidget { )), )); } -} + + +} \ No newline at end of file diff --git a/lib/widgets/patients/patient_card/ShowTimer.dart b/lib/widgets/patients/patient_card/ShowTimer.dart new file mode 100644 index 00000000..b769588b --- /dev/null +++ b/lib/widgets/patients/patient_card/ShowTimer.dart @@ -0,0 +1,59 @@ + +import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class ShowTimer extends StatefulWidget { + final PatiantInformtion patientInfo; + + + const ShowTimer({ + Key key, this.patientInfo, + }) : super(key: key); + + @override + _ShowTimerState createState() => _ShowTimerState(); +} + +class _ShowTimerState extends State { + + int remainingTime = 600; + String displayTime = ''; + + @override + Widget build(BuildContext context) { + if (displayTime.isEmpty) { + startShowTimer(); + } + return AppText( + "$displayTime", + color: Colors.red, + textAlign: TextAlign.start, + fontWeight: FontWeight.bold, + fontSize: 11, + ); + } + + startShowTimer() { + // this.remainingTime--; + setState(() { + displayTime = this.generateShowTimerString(); + }); + + Future.delayed(Duration(seconds: 1), () { + if (this.remainingTime > 0) { + startShowTimer(); + } + }); + } + + generateShowTimerString() { + DateTime now = DateTime.now(); + DateTime liveCareDate = DateTime.parse(widget.patientInfo.arrivalTime); + String timer = AppDateUtils.differenceBetweenDateAndCurrent( + liveCareDate, context, isShowSecond: true, isShowDays: false); + + return timer; + } +} diff --git a/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart b/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart deleted file mode 100644 index d1385d0e..00000000 --- a/lib/widgets/patients/profile/PatientHeaderWidgetNoAvatar.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; - -class PatientHeaderWidgetNoAvatar extends StatelessWidget { - final PatiantInformtion patient; - - PatientHeaderWidgetNoAvatar(this.patient); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Container( - margin: EdgeInsets.all(16), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - patient.firstName! + ' ' + patient.lastName!, - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.2, - ), - Row( - children: [ - AppText( - "VIP", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.2, - ), - SizedBox( - width: 8, - ), - AppText( - " ${patient.age}", - fontWeight: FontWeight.normal, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - ], - ), - AppText( - patient.visitType ?? "", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - AppText( - "${patient.companyName != null ? patient.companyName : ""}", - fontWeight: FontWeight.bold, - fontSize: SizeConfig.textMultiplier * 2.0, - ), - ], - ), - ), - Icon( - Icons.info_outline, - color: Colors.black, - ), - ], - ), - ), - Container( - width: double.infinity, - height: 1, - color: Color(0xffCCCCCC), - ), - ], - ); - } -} diff --git a/lib/widgets/patients/profile/PatientProfileButton.dart b/lib/widgets/patients/profile/PatientProfileButton.dart index 9c5b057d..31d281ae 100644 --- a/lib/widgets/patients/profile/PatientProfileButton.dart +++ b/lib/widgets/patients/profile/PatientProfileButton.dart @@ -28,6 +28,7 @@ class PatientProfileButton extends StatelessWidget { final bool isDartIcon; final IconData? dartIcon; final bool isFromLiveCare; + final Color color; PatientProfileButton({ Key? key, @@ -48,7 +49,7 @@ class PatientProfileButton extends StatelessWidget { this.isSelectInpatient = false, this.isDartIcon = false, this.dartIcon, - this.isFromLiveCare = false, + this.isFromLiveCare = false, this.color, }) : super(key: key); @override @@ -77,7 +78,7 @@ class PatientProfileButton extends StatelessWidget { ? Icon( dartIcon, size: 30, - color: Color(0xFF333C45), + color: color?? Color(0xFF333C45), ) : new Image.asset( url + icon, @@ -96,14 +97,14 @@ class PatientProfileButton extends StatelessWidget { children: [ AppText( !projectsProvider.isArabic ? this.nameLine1 : nameLine2, - color: Color(0xFF2B353E), + color: color??Color(0xFF2B353E), fontWeight: FontWeight.w600, textAlign: TextAlign.left, fontSize: SizeConfig.textMultiplier * 1.5, ), AppText( !projectsProvider.isArabic ? this.nameLine2 : nameLine1, - color: Color(0xFF2B353E), + color: color??Color(0xFF2B353E), fontWeight: FontWeight.w600, textAlign: TextAlign.left, fontSize: SizeConfig.textMultiplier * 1.5, @@ -119,7 +120,7 @@ class PatientProfileButton extends StatelessWidget { color: isDisable ? Colors.grey.withOpacity(0.4) : Colors.white, borderRadius: BorderRadius.all(Radius.circular(10)), border: Border.fromBorderSide(BorderSide( - color: Color(0xffBBBBBB), + color: color??Color(0xffBBBBBB), width: 1, )), ), diff --git a/lib/widgets/patients/profile/patient-page-header-widget.dart b/lib/widgets/patients/profile/patient-page-header-widget.dart deleted file mode 100644 index b3915b2c..00000000 --- a/lib/widgets/patients/profile/patient-page-header-widget.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:doctor_app_flutter/core/enum/master_lookup_key.dart'; -import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/SOAP/GeneralGetReqForSOAP.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/screens/base/base_view.dart'; -import 'package:doctor_app_flutter/screens/patients/profile/profile_screen/patient_profile_screen.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class PatientPageHeaderWidget extends StatelessWidget { - final PatiantInformtion patient; - PatientPageHeaderWidget(this.patient); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - - return BaseView( - onModelReady: (model) async { - GeneralGetReqForSOAP generalGetReqForSOAP = - GeneralGetReqForSOAP(patientMRN: patient.patientMRN ?? patient.patientId, doctorID: '', editedBy: ''); - await model.getPatientAllergy(generalGetReqForSOAP); - if (model.allergiesList.length == 0) { - await model.getMasterLookup(MasterKeysService.Allergies); - } - if (model.allergySeverityList.length == 0) { - await model.getMasterLookup(MasterKeysService.AllergySeverity); - } - }, - builder: (_, model, w) => Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - AvatarWidget( - Icon( - patient.genderDescription == "Male" ? DoctorApp.male : DoctorApp.female_icon, - size: 70, - color: Colors.white, - ), - ), - SizedBox( - width: 20, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SizedBox( - height: 5, - ), - AppText( - patient.patientDetails!.fullName != null - ? patient.patientDetails!.fullName - : patient.firstName, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).age, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - SizedBox( - width: 20, - ), - AppText( - patient.age.toString(), - color: Colors.black, - fontWeight: FontWeight.normal, - ), - ], - ), - model.patientAllergiesList.isNotEmpty && - model.getAllergicNames(projectViewModel.isArabic) != '' - ? AppText( - TranslationBase.of(context).allergicTO ?? - "" + " : " + model.getAllergicNames(projectViewModel.isArabic), - color: Color(0xFFB9382C), - fontWeight: FontWeight.bold, - ) - : AppText(''), - ], - ), - ) - ], - ), - ), - Container( - width: double.infinity, - height: 1, - color: Color(0xffCCCCCC), - ), - SizedBox( - width: 20, - ), - ], - ), - )); - } -} diff --git a/lib/widgets/patients/profile/patient-profile-app-bar.dart b/lib/widgets/patients/profile/patient-profile-app-bar.dart new file mode 100644 index 00000000..c39caef1 --- /dev/null +++ b/lib/widgets/patients/profile/patient-profile-app-bar.dart @@ -0,0 +1,594 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; +import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; +import 'package:doctor_app_flutter/util/date-utils.dart'; +import 'package:doctor_app_flutter/util/helpers.dart'; +import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'large_avatar.dart'; + +class PatientProfileAppBar extends StatelessWidget + with PreferredSizeWidget { + final PatientProfileAppBarModel patientProfileAppBarModel; + final bool isFromLabResult; + final VoidCallback onPressed; + + PatientProfileAppBar( + {this.patientProfileAppBarModel, this.isFromLabResult=false, this.onPressed}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + int gender = 1; + if (patientProfileAppBarModel.patient.patientDetails != null) { + gender = patientProfileAppBarModel.patient.patientDetails.gender; + } else { + gender = patientProfileAppBarModel.patient.gender; + } + + return Container( + padding: EdgeInsets.only( + left: 0, + right: 5, + bottom: 5, + ), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + margin: EdgeInsets.only(top: 50), + child: Column( + children: [ + Container( + padding: EdgeInsets.only(left: 12.0), + child: Row(children: [ + IconButton( + icon: Icon(Icons.arrow_back_ios), + color: Color(0xFF2B353E), //Colors.black, + onPressed: () { + if(onPressed!=null) + onPressed(); + Navigator.pop(context); + }, + ), + Expanded( + child: AppText( + patientProfileAppBarModel.patient.firstName != null + ? (Helpers.capitalize( + patientProfileAppBarModel.patient.firstName) + + " " + + Helpers.capitalize( + patientProfileAppBarModel.patient.lastName)) + : Helpers.capitalize( + patientProfileAppBarModel.patient.fullName ?? + patientProfileAppBarModel + .patient.patientDetails.fullName), + fontSize: SizeConfig.textMultiplier * 1.8, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + color: Color(0xFF2B353E), + ), + ), + gender == 1 + ? Icon( + DoctorApp.male_2, + color: Colors.blue, + ) + : Icon( + DoctorApp.female_1, + color: Colors.pink, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 4), + child: InkWell( + onTap: () { + launch("tel://" + + patientProfileAppBarModel.patient.mobileNumber); + }, + child: Icon( + Icons.phone, + color: Colors.black87, + ), + ), + ), + ]), + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 12.0), + child: Container( + width: 60, + height: 60, + child: Image.asset( + gender == 1 + ? 'assets/images/male_avatar.png' + : 'assets/images/female_avatar.png', + fit: BoxFit.cover, + ), + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + patientProfileAppBarModel.patient.patientStatusType != null + ? Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + patientProfileAppBarModel + .patient.patientStatusType == + 43 + ? AppText( + TranslationBase.of(context).arrivedP, + color: Colors.green, + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ) + : AppText( + TranslationBase.of(context).notArrived, + color: Colors.red[800], + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + fontSize: 12, + ), + patientProfileAppBarModel.patient.startTime != + null + ? AppText( + patientProfileAppBarModel + .patient.startTime != + null + ? patientProfileAppBarModel + .patient.startTime + : '', + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A)) + : SizedBox() + ], + )) + : SizedBox(), + + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black), + children: [ + new TextSpan( + text: TranslationBase.of(context).fileNumber, + style: TextStyle( + fontSize: 10, + fontFamily: 'Poppins', + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + ), + ), + new TextSpan( + text: patientProfileAppBarModel + .patient.patientId + .toString(), + style: TextStyle( + fontWeight: FontWeight.w700, + fontFamily: 'Poppins', + fontSize: 12, + color: Color(0xFF2E303A), + )), + ], + ), + ), + Row( + children: [ + AppText( + patientProfileAppBarModel.patient.nationalityName ?? + patientProfileAppBarModel + .patient.nationality ?? + patientProfileAppBarModel + .patient.nationalityId ?? + '', + fontWeight: FontWeight.bold, + fontSize: 12, + ), + patientProfileAppBarModel + .patient.nationalityFlagURL != + null + ? ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: Image.network( + patientProfileAppBarModel + .patient.nationalityFlagURL, + height: 25, + width: 30, + errorBuilder: (BuildContext context, + Object exception, + StackTrace stackTrace) { + return Text('No Image'); + }, + )) + : SizedBox() + ], + ) + ], + ), + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: TranslationBase.of(context).age + " : ", + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + )), + new TextSpan( + text: + "${AppDateUtils.getAgeByBirthday(patientProfileAppBarModel.patient.patientDetails != null ? patientProfileAppBarModel.patient.patientDetails.dateofBirth ?? "" : patientProfileAppBarModel.patient.dateofBirth ?? "", context, isServerFormat: !patientProfileAppBarModel.isFromLiveCare)}", + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + )), + ], + ), + ), + ), + + if (patientProfileAppBarModel.patient.appointmentDate != + null && + patientProfileAppBarModel + .patient.appointmentDate.isNotEmpty && !isFromLabResult) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AppText( + TranslationBase.of(context).appointmentDate + " : ", + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + ), + SizedBox( + width: 3.5, + ), + AppText( + AppDateUtils.getDayMonthYearDateFormatted( + AppDateUtils.convertStringToDate( + patientProfileAppBarModel + .patient.appointmentDate)), + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ), + SizedBox( + height: 0.5, + ) + ], + ), + if (patientProfileAppBarModel.isFromLabResult) + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 1.6 * SizeConfig.textMultiplier, + color: Colors.black, + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: "Result Date: ", + style: TextStyle( + fontSize: 10, + color: Color(0xFF575757), + fontWeight: FontWeight.w600, + fontFamily: 'Poppins', + )), + new TextSpan( + text: + '${AppDateUtils.getDayMonthYearDateFormatted(patientProfileAppBarModel.appointmentDate, isArabic: projectViewModel.isArabic)}', + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 12)), + ], + ), + ), + ), + // if(isInpatient) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (patientProfileAppBarModel.patient.admissionDate != + null && + patientProfileAppBarModel + .patient.admissionDate.isNotEmpty) + Container( + child: RichText( + text: new TextSpan( + style: new TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + fontFamily: 'Poppins', + ), + children: [ + new TextSpan( + text: patientProfileAppBarModel + .patient.admissionDate == + null + ? "" + : TranslationBase.of(context) + .admissionDate + + " : ", + style: TextStyle(fontSize: 10)), + new TextSpan( + text: patientProfileAppBarModel + .patient.admissionDate == + null + ? "" + : "${AppDateUtils.getDayMonthYearDateFormatted((AppDateUtils.getDateTimeFromServerFormat(patientProfileAppBarModel.patient.admissionDate.toString())))}", + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + )), + ]))), + if (patientProfileAppBarModel.patient.admissionDate != + null) + Row( + children: [ + AppText( + "${TranslationBase.of(context).numOfDays}: ", + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757)), + if (patientProfileAppBarModel + .isDischargedPatient && + patientProfileAppBarModel + .patient.dischargeDate != + null) + AppText( + "${AppDateUtils.getDateTimeFromServerFormat(patientProfileAppBarModel.patient.dischargeDate).difference(AppDateUtils.getDateTimeFromServerFormat(patientProfileAppBarModel.patient.admissionDate)).inDays + 1}", + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ) + else + AppText( + "${DateTime.now().difference(AppDateUtils.getDateTimeFromServerFormat(patientProfileAppBarModel.patient.admissionDate)).inDays + 1}", + fontWeight: FontWeight.w700, + fontSize: 12, + color: Color(0xFF2E303A), + ), + ], + ), + ], + ), + ], + ), + ), + ]), + if (patientProfileAppBarModel.isAppointmentHeader) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 30, + height: 30, + margin: EdgeInsets.only( + left: projectViewModel.isArabic ? 10 : 85, + right: projectViewModel.isArabic ? 85 : 10, + top: 5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + border: Border( + bottom: + BorderSide(color: Colors.grey[400], width: 2.5), + left: BorderSide(color: Colors.grey[400], width: 2.5), + )), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: LargeAvatar( + name: patientProfileAppBarModel.doctorName ?? "", + url: patientProfileAppBarModel.profileUrl, + ), + width: 25, + height: 25, + margin: EdgeInsets.only(top: 10), + ), + Expanded( + flex: 5, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppText( + '${TranslationBase.of(context).dr}${patientProfileAppBarModel.doctorName}', + color: Color(0xFF2E303A), + fontWeight: FontWeight.w700, + fontSize: 12, + ), + if (patientProfileAppBarModel.orderNo != + null && + !patientProfileAppBarModel + .isPrescriptions) + Row( + children: [ + AppText( + 'Order No: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .orderNo ?? + '', + fontSize: 12) + ], + ), + if (patientProfileAppBarModel.invoiceNO != + null && + !patientProfileAppBarModel + .isPrescriptions) + Row( + children: [ + AppText( + 'Invoice: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .invoiceNO ?? + "", + fontSize: 12) + ], + ), + if (patientProfileAppBarModel.branch != + null) + Row( + children: [ + AppText( + 'Branch: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .branch ?? + '', + fontSize: 12) + ], + ), + if (patientProfileAppBarModel.clinic != + null) + Row( + children: [ + AppText( + 'Clinic: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .clinic ?? + '', + fontSize: 12) + ], + ), + if (patientProfileAppBarModel + .isMedicalFile && + patientProfileAppBarModel.episode != + null) + Row( + children: [ + AppText( + 'Episode: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .episode ?? + '', + fontSize: 12) + ], + ), + if (patientProfileAppBarModel + .isMedicalFile && + patientProfileAppBarModel.visitDate != + null) + Row( + children: [ + AppText( + 'Visit Date: ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + patientProfileAppBarModel + .visitDate ?? + '', + fontSize: 12) + ], + ), + if (!patientProfileAppBarModel + .isMedicalFile) + Row( + children: [ + AppText( + !patientProfileAppBarModel + .isPrescriptions + ? 'Result Date:' + : 'Prescriptions Date ', + fontSize: 10, + fontWeight: FontWeight.w600, + color: Color(0xFF575757), + ), + AppText( + '${AppDateUtils.getDayMonthYearDateFormatted(patientProfileAppBarModel.appointmentDate, isArabic: projectViewModel.isArabic)}', + fontSize: 12, + ) + ], + ) + ]), + ), + ), + ], + ), + ), + ), + ], + ) + ], + ), + ), + ); + } + + @override + Size get preferredSize => Size( + double.maxFinite, + patientProfileAppBarModel.height == 0 + ? patientProfileAppBarModel.isAppointmentHeader + ? 270 + : ((patientProfileAppBarModel.patient.appointmentDate != null &&patientProfileAppBarModel.patient.appointmentDate.isNotEmpty ) + ? patientProfileAppBarModel.isFromLabResult?170:150 + : patientProfileAppBarModel.patient.admissionDate != null + ? patientProfileAppBarModel.isFromLabResult?170:150 + : patientProfileAppBarModel.isDischargedPatient + ? 240 + : 130) + : patientProfileAppBarModel.height); +} diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart index 39b5ed35..251d2e65 100644 --- a/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart +++ b/lib/widgets/patients/profile/patient-profile-header-new-design-app-bar.dart @@ -20,8 +20,10 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget with Preferred final bool isDischargedPatient; final bool isFromLiveCare; + final Stream videoCallDurationStream; + PatientProfileHeaderNewDesignAppBar(this.patient, this.patientType, this.arrivalType, - {this.height = 0.0, this.isInpatient = false, this.isDischargedPatient = false, this.isFromLiveCare = false}); + {this.height = 0.0, this.isInpatient = false, this.isDischargedPatient = false, this.isFromLiveCare = false, this.videoCallDurationStream}); @override Widget build(BuildContext context) { @@ -89,6 +91,23 @@ class PatientProfileHeaderNewDesignAppBar extends StatelessWidget with Preferred ), ), ), + StreamBuilder( + stream: videoCallDurationStream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if(snapshot.hasData && snapshot.data != null) + return InkWell( + onTap: (){ + }, + child: Container( + decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(20)), + padding: EdgeInsets.symmetric(vertical: 2, horizontal: 10), + child: Text(snapshot.data, style: TextStyle(color: Colors.white),), + ), + ); + else + return Container(); + }, + ), ]), ), Row(children: [ diff --git a/lib/widgets/patients/profile/patient-profile-header-new-design.dart b/lib/widgets/patients/profile/patient-profile-header-new-design.dart deleted file mode 100644 index 825d02a4..00000000 --- a/lib/widgets/patients/profile/patient-profile-header-new-design.dart +++ /dev/null @@ -1,291 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:intl/intl.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class PatientProfileHeaderNewDesign extends StatelessWidget { - final PatiantInformtion patient; - final String patientType; - final String arrivalType; - final double height; - final bool isHaveMargin; - - PatientProfileHeaderNewDesign(this.patient, this.patientType, this.arrivalType, - {this.height = 0.0, this.isHaveMargin = true}); - - @override - Widget build(BuildContext context) { - int gender = 1; - if (patient.patientDetails != null) { - gender = patient.patientDetails!.gender!; - } else { - gender = patient.gender!; - } - - return Container( - padding: EdgeInsets.only( - left: 0, - right: 5, - bottom: 5, - ), - decoration: BoxDecoration( - color: Colors.white, - ), - height: height == 0 ? 200 : height, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - patient.firstName != null - ? (Helpers.capitalize(patient.firstName) + " " + Helpers.capitalize(patient.lastName)) - : Helpers.capitalize(patient.patientDetails!.fullName), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient.mobileNumber!); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ), - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 ? 'assets/images/male_avatar.png' : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType)] == "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient.arrivedOn == null - ? AppText( - patient.startTime != null ? patient.startTime : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - AppDateUtils.getDayMonthYearDateFormatted( - AppDateUtils.convertStringToDate(patient.arrivedOn ?? "")), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType)] == "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate! + " : ", - fontSize: 14, - ), - patient.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient.startTime ?? "", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2(patient.appointmentDate.toString() ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle(fontSize: 1.6 * SizeConfig.textMultiplier, color: Colors.black), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle(fontSize: 12, fontFamily: 'Poppins')), - new TextSpan( - text: patient.patientId.toString(), - style: TextStyle(fontWeight: FontWeight.w700, fontFamily: 'Poppins', fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient.nationalityName ?? patient.nationality ?? patient.nationalityId ?? '', - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient.nationalityFlagURL != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient.nationalityFlagURL ?? "", - height: 25, - width: 30, - errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: TranslationBase.of(context).age! + " : ", style: TextStyle(fontSize: 14)), - new TextSpan( - text: - "${AppDateUtils.getAgeByBirthday(patient.patientDetails != null ? patient.patientDetails!.dateofBirth ?? "" : patient.dateofBirth ?? "", context)}", - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String? newDate; - const start = "/Date("; - if (str.isNotEmpty) { - const end = "+0300)"; - - final startIndex = str.indexOf(start); - final endIndex = str.indexOf(end, startIndex + start.length); - - var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(str.substring(startIndex + start.length, endIndex))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - isToday(date) { - DateTime tempDate = new DateFormat("yyyy-MM-dd").parse(date); - return DateFormat("yyyy-MM-dd").format(tempDate) == DateFormat("yyyy-MM-dd").format(DateTime.now()); - } - - myBoxDecoration() { - return BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.green, - width: 5, - ), - ), - borderRadius: BorderRadius.circular(10)); - } -} diff --git a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart b/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart deleted file mode 100644 index 564a4e8c..00000000 --- a/lib/widgets/patients/profile/patient_profile_header_with_appointment_card_app_bar.dart +++ /dev/null @@ -1,410 +0,0 @@ -import 'package:doctor_app_flutter/config/config.dart'; -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; -import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; -import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; -import 'package:doctor_app_flutter/util/date-utils.dart'; -import 'package:doctor_app_flutter/util/helpers.dart'; -import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'large_avatar.dart'; - -class PatientProfileHeaderWhitAppointmentAppBar extends StatelessWidget with PreferredSizeWidget { - final PatiantInformtion? patient; - final String? patientType; - final String? arrivalType; - final String? doctorName; - final String? branch; - final DateTime? appointmentDate; - final String? profileUrl; - final String? invoiceNO; - final String? orderNo; - final bool isPrescriptions; - final bool isMedicalFile; - final String? episode; - final String? vistDate; - - final String? clinic; - PatientProfileHeaderWhitAppointmentAppBar( - {this.patient, - this.patientType, - this.arrivalType, - this.doctorName, - this.branch, - this.appointmentDate, - this.profileUrl, - this.invoiceNO, - this.orderNo, - this.isPrescriptions = false, - this.clinic, - this.isMedicalFile = false, - this.episode, - this.vistDate}); - - @override - Widget build(BuildContext context) { - ProjectViewModel projectViewModel = Provider.of(context); - int gender = 1; - // if (patient!.patientDetails! != null) { - // gender = patient!.patientDetails!.gender!; - // } else { - // gender = patient!.gender!; - // } - - return Container( - padding: EdgeInsets.only(left: 0, right: 5, bottom: 5, top: 5), - decoration: BoxDecoration( - color: Colors.white, - ), - //height: 300, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), - margin: EdgeInsets.only(top: 50), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.only(left: 12.0), - child: Row(children: [ - IconButton( - icon: Icon(Icons.arrow_back_ios), - color: Colors.black, //Colors.black, - onPressed: () => Navigator.pop(context), - ), - Expanded( - child: AppText( - patient!.firstName != null - ? (Helpers.capitalize(patient!.firstName) + " " + Helpers.capitalize(patient!.lastName)) - : Helpers.capitalize(patient!.fullName ?? patient?.patientDetails?.fullName ?? ""), - fontSize: SizeConfig.textMultiplier * 2.2, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - ), - ), - gender == 1 - ? Icon( - DoctorApp.male_2, - color: Colors.blue, - ) - : Icon( - DoctorApp.female_1, - color: Colors.pink, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 4), - child: InkWell( - onTap: () { - launch("tel://" + patient!.mobileNumber!); - }, - child: Icon( - Icons.phone, - color: Colors.black87, - ), - ), - ) - ]), - ), - Row(children: [ - Padding( - padding: EdgeInsets.only(left: 12.0), - child: Container( - width: 60, - height: 60, - child: Image.asset( - gender == 1 ? 'assets/images/male_avatar.png' : 'assets/images/female_avatar.png', - fit: BoxFit.cover, - ), - ), - ), - SizedBox( - width: 10, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SERVICES_PATIANT2[int.parse(patientType ?? "")] == "patientArrivalList" - ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - patient!.patientStatusType == 43 - ? AppText( - TranslationBase.of(context).arrivedP, - color: Colors.green, - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ) - : AppText( - TranslationBase.of(context).notArrived, - color: Colors.red[800], - fontWeight: FontWeight.bold, - fontFamily: 'Poppins', - fontSize: 12, - ), - arrivalType == '1' || patient!.arrivedOn == null - ? AppText( - patient!.startTime != null ? patient!.startTime : '', - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - : AppText( - AppDateUtils.convertStringToDateFormat( - patient!.arrivedOn ?? "", 'MM-dd-yyyy HH:mm'), - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - ) - ], - )) - : SizedBox(), - if (SERVICES_PATIANT2[int.parse(patientType ?? "")] == "List_MyOutPatient") - Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - AppText( - TranslationBase.of(context).appointmentDate! + " : ", - fontSize: 14, - ), - patient!.startTime != null - ? Container( - height: 15, - width: 60, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(25), - color: HexColor("#20A169"), - ), - child: AppText( - patient!.startTime ?? "", - color: Colors.white, - fontSize: 1.5 * SizeConfig.textMultiplier, - textAlign: TextAlign.center, - fontWeight: FontWeight.bold, - ), - ) - : SizedBox(), - SizedBox( - width: 3.5, - ), - Container( - child: AppText( - convertDateFormat2(patient!.appointmentDate.toString() ?? ''), - fontSize: 1.5 * SizeConfig.textMultiplier, - fontWeight: FontWeight.bold, - ), - ), - SizedBox( - height: 0.5, - ) - ], - ), - margin: EdgeInsets.only( - top: 8, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - RichText( - text: TextSpan( - style: TextStyle(fontSize: 1.6 * SizeConfig.textMultiplier, color: Colors.black), - children: [ - new TextSpan( - text: TranslationBase.of(context).fileNumber, - style: TextStyle(fontSize: 12, fontFamily: 'Poppins')), - new TextSpan( - text: patient?.patientId?.toString() ?? "", - style: TextStyle(fontWeight: FontWeight.w700, fontFamily: 'Poppins', fontSize: 14)), - ], - ), - ), - Row( - children: [ - AppText( - patient!.nationalityName ?? patient!.nationality ?? "", - fontWeight: FontWeight.bold, - fontSize: 12, - ), - patient!.nationality != null - ? ClipRRect( - borderRadius: BorderRadius.circular(20.0), - child: Image.network( - patient?.nationalityFlagURL ?? "", - height: 25, - width: 30, - errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) { - return Text('No Image'); - }, - )) - : SizedBox() - ], - ) - ], - ), - Container( - child: RichText( - text: new TextSpan( - style: new TextStyle( - fontSize: 1.6 * SizeConfig.textMultiplier, - color: Colors.black, - fontFamily: 'Poppins', - ), - children: [ - new TextSpan( - text: TranslationBase.of(context).age ?? "" + " : ", style: TextStyle(fontSize: 14)), - new TextSpan( - text: - "${AppDateUtils.getAgeByBirthday(patient!.patientDetails != null ? patient!.patientDetails!.dateofBirth! : patient!.dateofBirth!, context)}", - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14)), - ], - ), - ), - ), - ], - ), - ), - ]), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: 30, - height: 30, - margin: EdgeInsets.only( - left: projectViewModel.isArabic ? 10 : 85, right: projectViewModel.isArabic ? 85 : 10, top: 5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border( - bottom: BorderSide(color: Colors.grey[400]!, width: 2.5), - left: BorderSide(color: Colors.grey[400]!, width: 2.5), - )), - ), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: LargeAvatar( - name: doctorName ?? "", - url: profileUrl, - ), - width: 25, - height: 25, - margin: EdgeInsets.only(top: 10), - ), - Expanded( - flex: 5, - child: Container( - margin: EdgeInsets.all(10), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppText( - '${TranslationBase.of(context).dr}$doctorName', - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 9, - ), - if (orderNo != null && !isPrescriptions) - Row( - children: [ - AppText('Order No: ', color: Colors.grey[800], fontSize: 12), - AppText(orderNo ?? '', fontSize: 12) - ], - ), - if (invoiceNO != null && !isPrescriptions) - Row( - children: [ - AppText('Invoice: ', color: Colors.grey[800], fontSize: 12), - AppText(invoiceNO ?? "", fontSize: 12) - ], - ), - if (branch != null) - Row( - children: [ - AppText('Branch: ', color: Colors.grey[800], fontSize: 12), - AppText(branch ?? '', fontSize: 12) - ], - ), - if (clinic != null) - Row( - children: [ - AppText('Clinic: ', color: Colors.grey[800], fontSize: 12), - AppText(clinic ?? '', fontSize: 12) - ], - ), - if (isMedicalFile && episode != null) - Row( - children: [ - AppText('Episode: ', color: Colors.grey[800], fontSize: 12), - AppText(episode ?? '', fontSize: 12) - ], - ), - if (isMedicalFile && vistDate != null) - Row( - children: [ - AppText('Visit Date: ', color: Colors.grey[800], fontSize: 12), - AppText(vistDate ?? '', fontSize: 12) - ], - ), - if (!isMedicalFile) - Row( - children: [ - Expanded( - child: AppText( - !isPrescriptions ? 'Result Date: ' : 'Prescriptions Date ', - color: Colors.grey[800], - fontSize: 12, - ), - ), - AppText( - '${AppDateUtils.getDayMonthYearDateFormatted(appointmentDate!, isArabic: projectViewModel.isArabic)}', - fontSize: 14, - ) - ], - ) - ]), - ), - ), - ], - ), - ), - ), - ], - ) - ], - ), - ), - ); - } - - convertDateFormat2(String str) { - String newDate = ""; - const start = "/Date("; - const end = "+0300)"; - - if (str.isNotEmpty) { - final startIndex = str.indexOf(start); - final endIndex = str.indexOf(end, startIndex + start.length); - - var date = new DateTime.fromMillisecondsSinceEpoch(int.parse(str.substring(startIndex + start.length, endIndex))); - newDate = date.year.toString() + - "/" + - date.month.toString().padLeft(2, '0') + - "/" + - date.day.toString().padLeft(2, '0'); - } - - return newDate.toString(); - } - - @override - Size get preferredSize => Size(double.maxFinite, 310); -} diff --git a/lib/widgets/patients/profile/profile-welcome-widget.dart b/lib/widgets/patients/profile/profile-welcome-widget.dart index 656dfd73..207c6986 100644 --- a/lib/widgets/patients/profile/profile-welcome-widget.dart +++ b/lib/widgets/patients/profile/profile-welcome-widget.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/core/viewModel/authentication_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -20,12 +21,9 @@ class ProfileWelcomeWidget extends StatelessWidget { widthFactor: 0.9, child: Row( mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ this.isClinic == true ? clinicWidget : SizedBox(), - SizedBox( - width: 20, - ), if (authenticationViewModel.doctorProfile != null) CircleAvatar( // radius: (52) @@ -34,8 +32,8 @@ class ProfileWelcomeWidget extends StatelessWidget { child: Image.network( authenticationViewModel.doctorProfile!.doctorImageURL ?? "", fit: BoxFit.fill, - width: 75, - height: 75, + width: SizeConfig.widthMultiplier* 11, + height: SizeConfig.widthMultiplier* 11, ), ), backgroundColor: Colors.transparent, diff --git a/lib/widgets/shared/app_drawer_widget.dart b/lib/widgets/shared/app_drawer_widget.dart index 7c7c9aba..ae51555a 100644 --- a/lib/widgets/shared/app_drawer_widget.dart +++ b/lib/widgets/shared/app_drawer_widget.dart @@ -4,7 +4,6 @@ import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/screens/reschedule-leaves/add-rescheduleleave.dart'; import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; -import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:provider/provider.dart'; @@ -30,6 +29,7 @@ class _AppDrawerState extends State { Widget build(BuildContext context) { AuthenticationViewModel authenticationViewModel = Provider.of(context); projectsProvider = Provider.of(context); + double drawerWidth = SizeConfig.realScreenWidth * 0.60; return RoundedContainer( child: Container( color: Colors.white, @@ -40,7 +40,6 @@ class _AppDrawerState extends State { child: ListView(padding: EdgeInsets.zero, children: [ Container( margin: EdgeInsets.symmetric(horizontal: 15), - // height: SizeConfig.heightMultiplier * 50, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -49,8 +48,11 @@ class _AppDrawerState extends State { Container( child: Image.asset( 'assets/images/dr_app_logo.png', + width: SizeConfig.getWidthMultiplier( + width: drawerWidth) * (SizeConfig.isHeightVeryShort? 25:SizeConfig.isHeightShort?32: 32), + ), - margin: EdgeInsets.only(top: 10, bottom: 10), + margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?1:2), bottom: SizeConfig.heightMultiplier * 0.5), ), Container( child: InkWell( @@ -59,16 +61,16 @@ class _AppDrawerState extends State { }, child: Icon( DoctorApp.close_1, - size: 20, + size: SizeConfig.heightMultiplier * 2, ), ), - margin: EdgeInsets.only(top: 20, bottom: 10), + margin: EdgeInsets.only(top: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?2:3), bottom: SizeConfig.heightMultiplier * 0.5), ) ], crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, ), - SizedBox(height: 5), + SizedBox(height: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?0.5:1),), if (authenticationViewModel.doctorProfile != null) InkWell( onTap: () { @@ -84,31 +86,41 @@ class _AppDrawerState extends State { Padding( padding: EdgeInsets.only(top: 10), child: AppText( - TranslationBase.of(context).dr ?? + TranslationBase + .of(context) + .dr ?? "" + authenticationViewModel.doctorProfile!.doctorName!, fontWeight: FontWeight.bold, color: Color(0xFF2E303A), fontFamily: 'Poppins', - fontSize: 17, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth( + width: drawerWidth) * (SizeConfig.isWidthLarge?5: 8), ), ), Padding( padding: EdgeInsets.only(top: 0), child: AppText( - authenticationViewModel.doctorProfile?.clinicDescription, + authenticationViewModel.doctorProfile + ?.clinicDescription, fontWeight: FontWeight.w600, color: Color(0xFF2E303A), - fontSize: 15, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth( + width: drawerWidth) * (SizeConfig.isWidthLarge?3: 6), fontFamily: 'Poppins', )) ], ), ), - SizedBox(height: 40), + SizedBox(height: SizeConfig.heightMultiplier * (SizeConfig.isHeightVeryShort?4:6),), InkWell( child: DrawerItem( - TranslationBase.of(context).applyOrRescheduleLeave!, + TranslationBase + .of(context) + .applyOrRescheduleLeave!, icon: DoctorApp.reschedule__1, + drawerWidth: drawerWidth, // subTitle: , ), onTap: () { @@ -121,19 +133,26 @@ class _AppDrawerState extends State { )); }, ), - SizedBox(height: 15), + SizedBox(height: SizeConfig.heightMultiplier *2), InkWell( child: DrawerItem( - TranslationBase.of(context).myQRCode!, + TranslationBase + .of(context) + .myQRCode!, icon: DoctorApp.qr_code_3, + drawerWidth: drawerWidth, + // subTitle: , ), ), - SizedBox(height: 15), + SizedBox(height: SizeConfig.heightMultiplier *1.5), InkWell( child: Container( - height: 80, - child: Image.asset('assets/images/qr_code.png'), + // height: 80, + child: Image.asset('assets/images/qr_code.png', + width: SizeConfig.getWidthMultiplier( + width: drawerWidth) * (SizeConfig.isHeightVeryShort?25:30), + ), ), onTap: () {}, ), @@ -141,7 +160,7 @@ class _AppDrawerState extends State { ), ), SizedBox( - height: MediaQuery.of(context).size.height * 0.09, + height: SizeConfig.heightMultiplier *(SizeConfig.isHeightVeryShort?8:SizeConfig.isHeightShort?10:16), ), Container( margin: EdgeInsets.symmetric(horizontal: 20), @@ -149,13 +168,19 @@ class _AppDrawerState extends State { children: [ InkWell( child: DrawerItem( + projectsProvider.isArabic - ? TranslationBase.of(context).lanEnglish ?? "" - : TranslationBase.of(context).lanArabic ?? "", + ? TranslationBase + .of(context) + .lanEnglish ?? "" + : TranslationBase + .of(context) + .lanArabic ?? "", // icon: DoctorApp.qr_code, assetLink: projectsProvider.isArabic ? 'assets/images/usa-flag.png' : 'assets/images/saudi-arabia-flag.png', + drawerWidth: drawerWidth, ), onTap: () { if (projectsProvider.isArabic) @@ -164,11 +189,15 @@ class _AppDrawerState extends State { projectsProvider.changeLanguage('ar'); }, ), - SizedBox(height: 10), + SizedBox(height: SizeConfig.heightMultiplier *(SizeConfig.isHeightVeryShort?0.5:1) ), InkWell( child: DrawerItem( - TranslationBase.of(context).logout!, + TranslationBase + .of(context) + .logout!, icon: DoctorApp.logout_1, + drawerWidth: drawerWidth, + ), onTap: () async { Navigator.pop(context); @@ -184,7 +213,6 @@ class _AppDrawerState extends State { flex: 1, child: Column(children: [ Container( - // This align moves the children to the bottom child: Align( alignment: FractionalOffset.bottomCenter, child: Container( @@ -199,7 +227,9 @@ class _AppDrawerState extends State { style: TextStyle( color: Color(0xFF989898), fontWeight: FontWeight.bold, - fontSize: 14, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth( + width: drawerWidth) * (SizeConfig.isWidthLarge?4: 6), fontFamily: 'Poppins', ), children: [ @@ -207,24 +237,25 @@ class _AppDrawerState extends State { text: ' Cloud Solutions', style: TextStyle( color: Color(0xFF2E303A), - fontSize: 15, + fontSize: SizeConfig + .getTextMultiplierBasedOnWidth( + width: drawerWidth) * (SizeConfig.isWidthLarge?5: 7), fontFamily: 'Poppins', ), ) ]), ), ), - // Text("Powered by"), Image.asset( 'assets/images/cs_logo_container.png', width: SizeConfig.imageSizeMultiplier * 20, ) ], - )))) + )))) ])) - ])), + ])), ), - width: SizeConfig.realScreenWidth * 0.60, + width: drawerWidth, margin: EdgeInsets.all(0), customCornerRaduis: false, diff --git a/lib/widgets/shared/app_scaffold_widget.dart b/lib/widgets/shared/app_scaffold_widget.dart index 7500145d..fa09aa72 100644 --- a/lib/widgets/shared/app_scaffold_widget.dart +++ b/lib/widgets/shared/app_scaffold_widget.dart @@ -2,7 +2,9 @@ import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; +import 'package:doctor_app_flutter/models/patient/profile/patient_profile_app_bar_model.dart'; import 'package:doctor_app_flutter/routes.dart'; +import 'package:doctor_app_flutter/widgets/patients/profile/patient-profile-app-bar.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -19,8 +21,13 @@ class AppScaffold extends StatelessWidget { final Widget? bottomSheet; final Color? backgroundColor; final PreferredSizeWidget? appBar; + final Widget drawer; + final Widget bottomNavigationBar; final String? subtitle; final bool isHomeIcon; + final bool extendBody; + final PatientProfileAppBarModel patientProfileAppBarModel; + AppScaffold( {this.appBarTitle = '', this.body, @@ -30,8 +37,10 @@ class AppScaffold extends StatelessWidget { this.bottomSheet, this.backgroundColor, this.isHomeIcon = true, - this.appBar, - this.subtitle}); + + this.subtitle, + this.patientProfileAppBarModel, + this.drawer, this.extendBody = false, this.bottomNavigationBar, this.appBar}); @override Widget build(BuildContext context) { @@ -43,19 +52,24 @@ class AppScaffold extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor ?? Colors.white, + drawer: drawer, + extendBody: extendBody, + bottomNavigationBar: bottomNavigationBar, appBar: isShowAppBar - ? appBar ?? - AppBar( - elevation: 0, - backgroundColor: Colors.white, //HexColor('#515B5D'), - textTheme: TextTheme( - headline6: TextStyle( - color: Colors.black87, - fontSize: 16.8, - )), - title: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ + ? patientProfileAppBarModel != null ? PatientProfileAppBar( + patientProfileAppBarModel: patientProfileAppBarModel,) : appBar ?? + AppBar( + elevation: 0, + backgroundColor: Colors.white, + //HexColor('#515B5D'), + textTheme: TextTheme( + headline6: TextStyle( + color: Colors.black87, + fontSize: 16.8, + )), + title: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ Text(appBarTitle.toUpperCase()), if (subtitle != null) Text( diff --git a/lib/widgets/shared/app_texts_widget.dart b/lib/widgets/shared/app_texts_widget.dart index ff9e8e4a..6c46ea36 100644 --- a/lib/widgets/shared/app_texts_widget.dart +++ b/lib/widgets/shared/app_texts_widget.dart @@ -18,6 +18,7 @@ class AppText extends StatefulWidget { final double? marginRight; final double? marginBottom; final double? marginLeft; + final double letterSpacing; final TextAlign? textAlign; final bool? bold; final bool? regular; @@ -56,6 +57,7 @@ class AppText extends StatefulWidget { this.visibility = true, this.textOverflow, this.textDecoration, + this.letterSpacing, }); @override @@ -119,14 +121,14 @@ class _AppTextState extends State { fontWeight: widget.fontWeight ?? _getFontWeight(), height: widget.fontHeight) : TextStyle( - fontStyle: widget.italic! ? FontStyle.italic : null, + fontStyle: widget.italic! ? FontStyle.italic : null, color: widget.color != null ? widget.color : Colors.black, fontSize: widget.fontSize ?? _getFontSize(), - letterSpacing: widget.variant == "overline" ? 1.5 : null, - fontWeight: widget.fontWeight ?? _getFontWeight(), - fontFamily: widget.fontFamily ?? 'Poppins', - decoration: widget.textDecoration, - height: widget.fontHeight), + letterSpacing: widget.letterSpacing, + fontWeight: widget.fontWeight ?? _getFontWeight(), + fontFamily: widget.fontFamily ?? 'Poppins', + decoration: widget.textDecoration, + height: widget.fontHeight), ), if (widget.readMore! && text.length > widget.maxLength! && hidden) Positioned( diff --git a/lib/widgets/shared/bottom_navigation_item.dart b/lib/widgets/shared/bottom_navigation_item.dart index 4a20864b..7e2b4de8 100644 --- a/lib/widgets/shared/bottom_navigation_item.dart +++ b/lib/widgets/shared/bottom_navigation_item.dart @@ -1,3 +1,4 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -16,7 +17,8 @@ class BottomNavigationItem extends StatelessWidget { Widget build(BuildContext context) { return Expanded( child: SizedBox( - height: 70.0, + height: SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 10 :SizeConfig.isHeightShort ? 8: 8), child: Material( type: MaterialType.transparency, child: InkWell( @@ -27,21 +29,24 @@ class BottomNavigationItem extends StatelessWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: 15, - ), + SizedBox(height: SizeConfig.getHeightMultiplier(height:SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 12:SizeConfig.isHeightShort ?10 : 9) ) * 10,), Container( + margin: EdgeInsets.only(bottom: 3), child: Icon(currentIndex == index ? activeIcon : icon, - color: currentIndex == index ? Color(0xFF333C45) : Theme.of(context).dividerColor, size: 22.0), + color: currentIndex == index ? Color(0xFF333C45) : Color(0xFF989898), size: SizeConfig.getHeightMultiplier(height:SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 10:SizeConfig.isHeightShort ?8.5 : 7) ) * 40,), ), SizedBox( - height: 5, + height: SizeConfig.getHeightMultiplier(height:SizeConfig.heightMultiplier * + (SizeConfig.isHeightVeryShort ? 10 : 6) ) * 0.5, ), Expanded( child: Text( name ?? "", + textAlign: TextAlign.center, style: TextStyle( - color: currentIndex == index ? Theme.of(context).primaryColor : Theme.of(context).dividerColor, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth() * 2,color: currentIndex == index ? Color(0xFF333C45) : Color(0xFF989898)//#989898, ), ), ), diff --git a/lib/widgets/shared/buttons/app_buttons_widget.dart b/lib/widgets/shared/buttons/app_buttons_widget.dart index 682be89b..4b80ae0a 100644 --- a/lib/widgets/shared/buttons/app_buttons_widget.dart +++ b/lib/widgets/shared/buttons/app_buttons_widget.dart @@ -22,6 +22,7 @@ class AppButton extends StatefulWidget { final double? radius; final double? vPadding; final double? hPadding; + final double height; AppButton({ @required this.onPressed, @@ -39,7 +40,7 @@ class AppButton extends StatefulWidget { this.hPadding = 0, this.radius = 8.0, this.hasBorder = false, - this.borderColor, + this.borderColor, this.height, }); _AppButtonState createState() => _AppButtonState(); @@ -49,7 +50,7 @@ class _AppButtonState extends State { @override Widget build(BuildContext context) { return Container( - // height: MediaQuery.of(context).size.height * 0.075, + height: widget.height, child: IgnorePointer( ignoring: widget.loading! || widget.disabled!, child: RawMaterialButton( diff --git a/lib/widgets/shared/drawer_item_widget.dart b/lib/widgets/shared/drawer_item_widget.dart index 17c593f8..4a38bfac 100644 --- a/lib/widgets/shared/drawer_item_widget.dart +++ b/lib/widgets/shared/drawer_item_widget.dart @@ -11,8 +11,9 @@ class DrawerItem extends StatefulWidget { final IconData? icon; final Color? color; final String? assetLink; + final double drawerWidth; - DrawerItem(this.title, {this.icon, this.color, this.subTitle = '', this.assetLink}); + DrawerItem(this.title, {this.icon, this.color, this.subTitle = '', this.assetLink, this.drawerWidth}); @override _DrawerItemState createState() => _DrawerItemState(); @@ -28,15 +29,15 @@ class _DrawerItemState extends State { children: [ if (widget.assetLink != null) Container( - height: 20, - width: 20, + height: SizeConfig.imageSizeMultiplier * (SizeConfig.isWidthLarge?3: 5), + width: SizeConfig.imageSizeMultiplier * (SizeConfig.isWidthLarge?3: 5), child: Image.asset(widget.assetLink!), ), if (widget.assetLink == null) Icon( widget.icon, color: widget.color ?? Colors.black87, - size: SizeConfig.imageSizeMultiplier * 5, + size: SizeConfig.imageSizeMultiplier * (SizeConfig.isWidthLarge?3: 5), ), Expanded( child: Column( @@ -50,7 +51,7 @@ class _DrawerItemState extends State { marginLeft: 5, marginRight: 5, color: widget.color ?? Color(0xFF2E303A), - fontSize: 14, + fontSize: SizeConfig.getTextMultiplierBasedOnWidth(width: widget.drawerWidth ) * (SizeConfig.isHeightVeryShort?5:(SizeConfig.isWidthLarge?4: 6)), fontFamily: 'Poppins', fontWeight: FontWeight.w600, ), diff --git a/pubspec.lock b/pubspec.lock index 859b1ad7..e4fdc2dc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,35 +7,35 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "22.0.0" + version: "12.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "1.7.1" + version: "0.40.6" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" + version: "2.5.0-nullsafety.1" autocomplete_textfield: dependency: "direct main" description: @@ -56,376 +56,355 @@ packages: name: bazel_worker url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.1.25" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.0-nullsafety.1" build: dependency: transitive description: name: build url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "1.6.2" build_config: dependency: transitive description: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.4.5" build_daemon: dependency: transitive description: name: build_daemon url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "2.1.7" build_modules: dependency: transitive description: name: build_modules url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "3.0.4" build_resolvers: dependency: transitive description: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "1.5.3" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "1.11.1" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "7.0.0" + version: "6.1.7" build_web_compilers: dependency: "direct dev" description: name: build_web_compilers url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "2.12.2" built_collection: dependency: transitive description: name: built_collection url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "4.3.2" built_value: dependency: transitive description: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.0.6" + version: "7.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.0-nullsafety.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.0-nullsafety.1" charts_common: dependency: transitive description: name: charts_common url: "https://pub.dartlang.org" source: hosted - version: "0.10.0" + version: "0.9.0" charts_flutter: dependency: "direct main" description: name: charts_flutter url: "https://pub.dartlang.org" source: hosted - version: "0.10.0" + version: "0.9.0" checked_yaml: dependency: transitive description: name: checked_yaml url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.4" chewie: dependency: transitive description: name: chewie url: "https://pub.dartlang.org" source: hosted - version: "1.2.2" + version: "0.9.10" chewie_audio: dependency: transitive description: name: chewie_audio url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.0.0+1" cli_util: dependency: transitive description: name: cli_util url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.0-nullsafety.1" code_builder: dependency: transitive description: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "3.7.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.15.0-nullsafety.3" connectivity: dependency: "direct main" description: name: connectivity url: "https://pub.dartlang.org" source: hosted - version: "3.0.6" + version: "0.4.9+5" connectivity_for_web: dependency: transitive description: name: connectivity_for_web url: "https://pub.dartlang.org" source: hosted - version: "0.4.0" + version: "0.3.1+4" connectivity_macos: dependency: transitive description: name: connectivity_macos url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.1.0+7" connectivity_platform_interface: dependency: transitive description: name: connectivity_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.6" convert: dependency: transitive description: name: convert url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "2.1.1" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.1.5" + css_colors: + dependency: transitive + description: + name: css_colors + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.17.0" + version: "0.16.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "0.1.3" dart_style: dependency: transitive description: name: dart_style url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.3.10" date_time_picker: dependency: "direct main" description: name: date_time_picker url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.1.1" device_info: dependency: "direct main" description: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "0.4.2+10" device_info_platform_interface: dependency: transitive description: name: device_info_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.1" dropdown_search: dependency: "direct main" description: name: dropdown_search url: "https://pub.dartlang.org" source: hosted - version: "0.6.2" + version: "0.4.9" equatable: dependency: transitive description: name: equatable url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "1.2.6" eva_icons_flutter: dependency: "direct main" description: name: eva_icons_flutter url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "2.0.1" expandable: dependency: "direct main" description: name: expandable url: "https://pub.dartlang.org" source: hosted - version: "5.0.1" + version: "4.1.4" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.0-nullsafety.1" ffi: dependency: transitive description: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "0.1.3" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.1" - file_picker: - dependency: "direct main" - description: - name: file_picker - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2+2" + version: "5.2.1" firebase_core: dependency: transitive description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "0.5.3" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "2.1.0" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "0.2.1+1" firebase_messaging: dependency: "direct main" description: name: firebase_messaging url: "https://pub.dartlang.org" source: hosted - version: "10.0.2" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" + version: "7.0.3" fixnum: dependency: transitive description: name: fixnum url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.10.11" fl_chart: dependency: "direct main" description: name: fl_chart url: "https://pub.dartlang.org" source: hosted - version: "0.36.1" + version: "0.12.3" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_colorpicker: - dependency: transitive - description: - name: flutter_colorpicker - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0" flutter_device_type: dependency: "direct main" description: name: flutter_device_type url: "https://pub.dartlang.org" source: hosted - version: "0.4.0" + version: "0.2.0" flutter_flexible_toast: dependency: "direct main" description: @@ -446,54 +425,19 @@ packages: name: flutter_html url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "1.0.2" flutter_inappwebview: dependency: transitive description: name: flutter_inappwebview url: "https://pub.dartlang.org" source: hosted - version: "5.3.2" - flutter_keyboard_visibility: - dependency: transitive - description: - name: flutter_keyboard_visibility - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.2" - flutter_keyboard_visibility_platform_interface: - dependency: transitive - description: - name: flutter_keyboard_visibility_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - flutter_keyboard_visibility_web: - dependency: transitive - description: - name: flutter_keyboard_visibility_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - flutter_layout_grid: - dependency: transitive - description: - name: flutter_layout_grid - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "4.0.0+4" flutter_localizations: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_math_fork: - dependency: transitive - description: - name: flutter_math_fork - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.3" flutter_page_indicator: dependency: transitive description: @@ -507,21 +451,21 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "1.0.11" flutter_staggered_grid_view: dependency: "direct main" description: name: flutter_staggered_grid_view url: "https://pub.dartlang.org" source: hosted - version: "0.4.0" + version: "0.3.4" flutter_svg: dependency: transitive description: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.22.0" + version: "0.18.1" flutter_swiper: dependency: "direct main" description: @@ -545,84 +489,77 @@ packages: name: font_awesome_flutter url: "https://pub.dartlang.org" source: hosted - version: "9.1.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" + version: "8.12.0" get_it: dependency: "direct main" description: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "7.1.3" + version: "4.0.4" glob: dependency: transitive description: name: glob url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.2.0" graphs: dependency: transitive description: name: graphs url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.2.0" hexcolor: dependency: "direct main" description: name: hexcolor url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "1.0.6" html: dependency: "direct main" description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.15.0" + version: "0.14.0+4" html_editor_enhanced: dependency: "direct main" description: name: html_editor_enhanced url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "1.3.0" http: dependency: "direct main" description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.3" + version: "0.12.2" http_interceptor: dependency: "direct main" description: name: http_interceptor url: "https://pub.dartlang.org" source: hosted - version: "0.4.1" + version: "0.2.0" http_multi_server: dependency: transitive description: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.2.0" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "3.1.4" imei_plugin: dependency: "direct main" description: @@ -630,321 +567,328 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" - infinite_listview: - dependency: transitive - description: - name: infinite_listview - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" intl: dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" source: hosted - version: "0.17.0" + version: "0.16.1" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.3.5" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.6.2" json_annotation: dependency: transitive description: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "3.1.1" local_auth: dependency: "direct main" description: name: local_auth url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "0.6.3+4" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "0.11.4" maps_launcher: dependency: "direct main" description: name: maps_launcher url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.2.2+2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.10-nullsafety.1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.0-nullsafety.3" mime: dependency: transitive description: name: mime url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.9.7" nested: dependency: transitive description: name: nested url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" - numberpicker: + version: "0.0.4" + node_interop: dependency: transitive description: - name: numberpicker + name: node_interop url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" - numerus: + version: "1.2.1" + node_io: dependency: transitive description: - name: numerus + name: node_io url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.2.0" + open_iconic_flutter: + dependency: transitive + description: + name: open_iconic_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.9.3" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.0-nullsafety.1" path_drawing: dependency: transitive description: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.5.1" + version: "0.4.1+1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.2.1" + version: "0.1.4" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.1+2" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.4" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "0.0.4+3" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.11.0" + version: "1.9.2" percent_indicator: dependency: "direct main" description: name: percent_indicator url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.1.9+1" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.1.0" + version: "5.1.0+2" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.6.0" + version: "2.0.2" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "3.1.0" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "2.2.1" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" - pointer_interceptor: - dependency: transitive - description: - name: pointer_interceptor - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.0+1" + version: "1.0.3" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.5.0" + version: "1.4.0" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.2.1" + version: "3.0.13" + progress_hud_v2: + dependency: "direct main" + description: + name: progress_hud_v2 + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" protobuf: dependency: transitive description: name: protobuf url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.1.3" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "4.3.3" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.4.4" pubspec_parse: dependency: transitive description: name: pubspec_parse url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.1.8" quiver: - dependency: transitive + dependency: "direct main" description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "2.1.5" scratch_space: dependency: transitive description: name: scratch_space url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.0.4+3" + screen: + dependency: transitive + description: + name: screen + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.5" shared_preferences: dependency: "direct main" description: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "0.5.12+4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.2+4" shared_preferences_macos: dependency: transitive description: name: shared_preferences_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.1+11" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" shared_preferences_web: dependency: transitive description: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.1.2+7" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.2+3" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "1.1.4" + version: "0.7.9" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "0.2.4+1" sky_engine: dependency: transitive description: flutter @@ -956,14 +900,14 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.10" + version: "0.10.9" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.0-nullsafety.2" speech_to_text: dependency: "direct main" description: @@ -977,56 +921,56 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0" + version: "1.10.0-nullsafety.1" sticky_headers: dependency: "direct main" description: name: sticky_headers url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.1.8+1" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.0-nullsafety.1" stream_transform: dependency: transitive description: name: stream_transform url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.2.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.0-nullsafety.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.0-nullsafety.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.2.19-nullsafety.2" timing: dependency: transitive description: name: timing url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.1.1+3" transformer_page_view: dependency: transitive description: @@ -1034,181 +978,146 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.6" - tuple: - dependency: transitive - description: - name: tuple - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.0-nullsafety.3" url_launcher: dependency: "direct main" description: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.0.6" + version: "5.7.10" url_launcher_linux: dependency: transitive description: name: url_launcher_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.1+4" url_launcher_macos: dependency: transitive description: name: url_launcher_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.1+9" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "1.0.9" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "0.1.5+3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "0.0.1+3" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.0-nullsafety.3" video_player: dependency: transitive description: name: video_player url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "0.10.12+5" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "2.2.0" video_player_web: dependency: transitive description: name: video_player_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" - visibility_detector: - dependency: transitive - description: - name: visibility_detector - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" + version: "0.1.4+1" wakelock: dependency: transitive description: name: wakelock url: "https://pub.dartlang.org" source: hosted - version: "0.5.2" - wakelock_macos: - dependency: transitive - description: - name: wakelock_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0+1" - wakelock_platform_interface: - dependency: transitive - description: - name: wakelock_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.1+1" - wakelock_web: - dependency: transitive - description: - name: wakelock_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+1" - wakelock_windows: - dependency: transitive - description: - name: wakelock_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0" + version: "0.1.4+2" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "0.9.7+15" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "1.2.0" webview_flutter: dependency: transitive description: name: webview_flutter url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "0.3.24" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "1.7.4+1" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.1.2" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.1.2" + version: "4.5.1" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "2.2.1" sdks: - dart: ">=2.13.0 <3.0.0" - flutter: ">=2.2.0" + dart: ">=2.10.0 <2.11.0" + flutter: ">=1.22.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index bc205213..e1040a32 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,7 +91,7 @@ dependencies: speech_to_text: path: speech_to_text - + quiver: ^2.1.5 # Html Editor Enhanced html_editor_enhanced: ^2.1.1