From fb47d6adfe26610c44819bd876a898c70171c558 Mon Sep 17 00:00:00 2001 From: sandesh Date: Sat, 16 May 2026 00:06:59 +1000 Subject: [PATCH] Implemented Nurse Profile module with backend integration and future-ready edit UI --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 47 ++--- .../guardian/model/NurseProfileResponse.kt | 32 ++++ .../guardian/services/api/ApiService.kt | 9 + .../guardian/view/general/Homepage4nurse.kt | 37 +++- .../view/general/NurseProfileActivity.kt | 101 ++++++++++ .../res/layout/activity_homepage4nurse.xml | 54 +++++- .../res/layout/activity_nurse_profile.xml | 174 ++++++++++++++++++ 8 files changed, 412 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/deakin/gopher/guardian/model/NurseProfileResponse.kt create mode 100644 app/src/main/java/deakin/gopher/guardian/view/general/NurseProfileActivity.kt create mode 100644 app/src/main/res/layout/activity_nurse_profile.xml diff --git a/app/build.gradle b/app/build.gradle index 18f94621d..63c83125e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -112,6 +112,7 @@ dependencies { implementation 'androidx.compose.material3:material3' implementation platform('androidx.compose:compose-bom:2024.08.00') implementation platform('androidx.compose:compose-bom:2024.08.00') + implementation 'androidx.activity:activity:1.8.0' testImplementation 'junit:junit:4.13.2' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 31d6a312a..2f47133cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,21 +5,15 @@ - - - - + + - - - - - - - - - + + + @@ -34,9 +28,12 @@ android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" + tools:ignore="ExtraText" tools:replace="android:allowBackup,android:label" - tools:targetApi="31" - tools:ignore="ExtraText"> + tools:targetApi="31"> + @@ -45,7 +42,7 @@ android:exported="false" /> + android:exported="false" /> @@ -161,7 +158,8 @@ - - - - - - - - - + - - + - @@ -228,7 +217,7 @@ android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> - + \ No newline at end of file diff --git a/app/src/main/java/deakin/gopher/guardian/model/NurseProfileResponse.kt b/app/src/main/java/deakin/gopher/guardian/model/NurseProfileResponse.kt new file mode 100644 index 000000000..dad10370b --- /dev/null +++ b/app/src/main/java/deakin/gopher/guardian/model/NurseProfileResponse.kt @@ -0,0 +1,32 @@ +package deakin.gopher.guardian.model + +data class NurseProfileResponse( + val _id: String?, + val fullname: String?, + val email: String?, + val role: NurseRole?, + val assignedPatients: List?, + val approvalStatus: String?, + val organization: NurseOrganization? +) + +data class NurseRole( + val _id: String?, + val name: String? +) + +data class AssignedPatient( + val _id: String?, + val fullname: String?, + val gender: String?, + val dateOfBirth: String?, + val age: Int?, + val id: String? +) + +data class NurseOrganization( + val _id: String?, + val name: String?, + val staffCount: Int?, + val id: String? +) \ No newline at end of file diff --git a/app/src/main/java/deakin/gopher/guardian/services/api/ApiService.kt b/app/src/main/java/deakin/gopher/guardian/services/api/ApiService.kt index 0e9ea177e..83df830a9 100644 --- a/app/src/main/java/deakin/gopher/guardian/services/api/ApiService.kt +++ b/app/src/main/java/deakin/gopher/guardian/services/api/ApiService.kt @@ -22,6 +22,7 @@ import retrofit2.http.POST import retrofit2.http.Part import retrofit2.http.Path import retrofit2.http.Query +import deakin.gopher.guardian.model.NurseProfileResponse interface ApiService { @POST("auth/register") @@ -60,6 +61,14 @@ interface ApiService { @Header("Authorization") token: String, ): Response> + @GET("nurse/profile") + suspend fun getNurseProfile( + @Header("Authorization") token: String, + @Query("email") email: String, + ): Response + + + @Multipart @POST("patients/add") suspend fun addPatient( diff --git a/app/src/main/java/deakin/gopher/guardian/view/general/Homepage4nurse.kt b/app/src/main/java/deakin/gopher/guardian/view/general/Homepage4nurse.kt index 4b529e376..7d9c806f2 100644 --- a/app/src/main/java/deakin/gopher/guardian/view/general/Homepage4nurse.kt +++ b/app/src/main/java/deakin/gopher/guardian/view/general/Homepage4nurse.kt @@ -9,32 +9,55 @@ import deakin.gopher.guardian.model.login.SessionManager import deakin.gopher.guardian.services.EmailPasswordAuthService import deakin.gopher.guardian.services.NavigationService +import android.content.Intent + + class Homepage4nurse : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_homepage4nurse) val user = SessionManager.getCurrentUser() - val titleText: TextView = findViewById(R.id.medicalDiagnosticsTitleTextView) + + val titleText: TextView = + findViewById(R.id.medicalDiagnosticsTitleTextView) + titleText.append(" ${user.name.split(" ").getOrNull(0) ?: ""}") - val patientsButton: Button = findViewById(R.id.patientsButton_nurse) - val settingsButton: Button = findViewById(R.id.settingsButton_nurse) - val signOutButton: Button = findViewById(R.id.sighOutButton_nurse) + val patientsButton: Button = + findViewById(R.id.patientsButton_nurse) + + val settingsButton: Button = + findViewById(R.id.settingsButton_nurse) + val signOutButton: Button = + findViewById(R.id.sighOutButton_nurse) + + val profileButton: Button = + findViewById(R.id.profileButton_nurse) + + // My Patients button patientsButton.setOnClickListener { NavigationService(this).onLaunchPatientList() } - // settings button + // Settings button settingsButton.setOnClickListener { NavigationService(this).onSettings() } - // sign out button + // My Profile button + profileButton.setOnClickListener { + val intent = Intent(this, NurseProfileActivity::class.java) + startActivity(intent) + } + + + // Sign Out button signOutButton.setOnClickListener { EmailPasswordAuthService.signOut(this) finish() } } -} +} \ No newline at end of file diff --git a/app/src/main/java/deakin/gopher/guardian/view/general/NurseProfileActivity.kt b/app/src/main/java/deakin/gopher/guardian/view/general/NurseProfileActivity.kt new file mode 100644 index 000000000..8a0d93f0f --- /dev/null +++ b/app/src/main/java/deakin/gopher/guardian/view/general/NurseProfileActivity.kt @@ -0,0 +1,101 @@ +package deakin.gopher.guardian.view.general + +import android.os.Bundle +import android.view.View +import android.widget.ProgressBar +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import deakin.gopher.guardian.R +import deakin.gopher.guardian.model.login.SessionManager +import deakin.gopher.guardian.services.api.ApiClient +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import android.widget.EditText +import android.widget.LinearLayout + +class NurseProfileActivity : AppCompatActivity() { + + private lateinit var tvNurseName: TextView + private lateinit var tvNurseEmail: TextView + private lateinit var tvNursePhone: TextView + private lateinit var tvNurseRole: TextView + private lateinit var tvError: TextView + private lateinit var progressBar: ProgressBar + private lateinit var tvEditHint: TextView + private lateinit var editFormContainer: LinearLayout + private lateinit var etNurseName: EditText + private lateinit var etNurseEmail: EditText + private lateinit var etNurseRole: EditText + private lateinit var etNurseOrganization: EditText + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_nurse_profile) + + tvNurseName = findViewById(R.id.tvNurseName) + tvNurseEmail = findViewById(R.id.tvNurseEmail) + tvNursePhone = findViewById(R.id.tvNursePhone) + tvNurseRole = findViewById(R.id.tvNurseRole) + tvError = findViewById(R.id.tvError) + tvEditHint = findViewById(R.id.tvEditHint) + + editFormContainer = findViewById(R.id.editFormContainer) + etNurseName = findViewById(R.id.etNurseName) + etNurseEmail = findViewById(R.id.etNurseEmail) + etNurseRole = findViewById(R.id.etNurseRole) + etNurseOrganization = findViewById(R.id.etNurseOrganization) + + findViewById(R.id.ivEditProfile).setOnClickListener { + tvEditHint.visibility = View.VISIBLE + editFormContainer.visibility = View.VISIBLE + + etNurseName.setText(tvNurseName.text.toString()) + etNurseEmail.setText(tvNurseEmail.text.toString()) + etNurseRole.setText(tvNurseRole.text.toString()) + etNurseOrganization.setText(tvNursePhone.text.toString().replace("Organization: ", "")) + } + progressBar = findViewById(R.id.progressBar) + + fetchNurseProfile() + } + + private fun fetchNurseProfile() { + val token = "Bearer ${SessionManager.getToken()}" + val email = SessionManager.getCurrentUser().email + + progressBar.visibility = View.VISIBLE + tvError.visibility = View.GONE + + CoroutineScope(Dispatchers.IO).launch { + val response = + try { + ApiClient.apiService.getNurseProfile(token, email) + } catch (e: Exception) { + println("NURSE_PROFILE_EXCEPTION: ${e.message}") + null + } + + withContext(Dispatchers.Main) { + progressBar.visibility = View.GONE + + if (response?.isSuccessful == true && response.body() != null) { + val nurseProfile = response.body()!! + + tvNurseName.text = nurseProfile.fullname ?: "Name not available" + tvNurseEmail.text = nurseProfile.email ?: "Email not available" + tvNurseRole.text = nurseProfile.role?.name ?: "Role not available" + tvNursePhone.text = + "Organization: ${nurseProfile.organization?.name ?: "Not available"}" + + tvError.visibility = View.GONE + } else { + tvError.visibility = View.VISIBLE + tvError.text = "Failed to load nurse profile" + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_homepage4nurse.xml b/app/src/main/res/layout/activity_homepage4nurse.xml index 2cd321f1e..8abccef1a 100644 --- a/app/src/main/res/layout/activity_homepage4nurse.xml +++ b/app/src/main/res/layout/activity_homepage4nurse.xml @@ -1,11 +1,12 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context="deakin.gopher.guardian.view.general.Homepage4nurse"> +