diff --git a/app/.idea/.gitignore b/app/.idea/.gitignore
new file mode 100644
index 000000000..26d33521a
--- /dev/null
+++ b/app/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/app/.idea/AndroidProjectSystem.xml b/app/.idea/AndroidProjectSystem.xml
new file mode 100644
index 000000000..4a53bee8c
--- /dev/null
+++ b/app/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/caches/deviceStreaming.xml b/app/.idea/caches/deviceStreaming.xml
new file mode 100644
index 000000000..c31fe546b
--- /dev/null
+++ b/app/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,1574 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml
new file mode 100644
index 000000000..9d8ba93b9
--- /dev/null
+++ b/app/.idea/gradle.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/migrations.xml b/app/.idea/migrations.xml
new file mode 100644
index 000000000..f8051a6f9
--- /dev/null
+++ b/app/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml
new file mode 100644
index 000000000..0573b9e5c
--- /dev/null
+++ b/app/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/runConfigurations.xml b/app/.idea/runConfigurations.xml
new file mode 100644
index 000000000..16660f1d8
--- /dev/null
+++ b/app/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/vcs.xml b/app/.idea/vcs.xml
new file mode 100644
index 000000000..6c0b86358
--- /dev/null
+++ b/app/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/.idea/.gitignore b/app/src/main/java/deakin/gopher/.idea/.gitignore
new file mode 100644
index 000000000..26d33521a
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/app/src/main/java/deakin/gopher/.idea/caches/deviceStreaming.xml b/app/src/main/java/deakin/gopher/.idea/caches/deviceStreaming.xml
new file mode 100644
index 000000000..c31fe546b
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,1574 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/.idea/libraries/KotlinJavaScript.xml b/app/src/main/java/deakin/gopher/.idea/libraries/KotlinJavaScript.xml
new file mode 100644
index 000000000..4b01461bc
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/libraries/KotlinJavaScript.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/.idea/misc.xml b/app/src/main/java/deakin/gopher/.idea/misc.xml
new file mode 100644
index 000000000..0abfbc5d3
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/misc.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/.idea/modules.xml b/app/src/main/java/deakin/gopher/.idea/modules.xml
new file mode 100644
index 000000000..aa13c142d
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/.idea/vcs.xml b/app/src/main/java/deakin/gopher/.idea/vcs.xml
new file mode 100644
index 000000000..821e530dd
--- /dev/null
+++ b/app/src/main/java/deakin/gopher/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/services/api/ApiClient.kt b/app/src/main/java/deakin/gopher/guardian/services/api/ApiClient.kt
index 48eff44c6..b98828cc9 100644
--- a/app/src/main/java/deakin/gopher/guardian/services/api/ApiClient.kt
+++ b/app/src/main/java/deakin/gopher/guardian/services/api/ApiClient.kt
@@ -7,7 +7,7 @@ import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
// private const val BASE_URL = "http://10.0.2.2:3000/api/v1/"
- private const val BASE_URL = "https://guardian-backend-opal.vercel.app/api/v1/"
+ private const val BASE_URL = "https://guardian-backend-ashen.vercel.app/api/v1/"
private val client = OkHttpClient()
private val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
diff --git a/app/src/main/java/deakin/gopher/guardian/view/general/TaskAddActivity.kt b/app/src/main/java/deakin/gopher/guardian/view/general/TaskAddActivity.kt
index cb8c1aed8..e8da4fab0 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/general/TaskAddActivity.kt
+++ b/app/src/main/java/deakin/gopher/guardian/view/general/TaskAddActivity.kt
@@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
-import android.widget.RadioGroup
+import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
@@ -18,8 +18,6 @@ class TaskAddActivity : AppCompatActivity() {
private lateinit var taskDescriptionEditText: EditText
private lateinit var patientIdEditText: EditText
private lateinit var taskSubDescEditText: EditText
- private lateinit var assignedNurseEditText: EditText
- private lateinit var priorityRadioGroup: RadioGroup
private var taskPriority: Priority = Priority.MEDIUM
private var task: Task? = null
@@ -31,16 +29,12 @@ class TaskAddActivity : AppCompatActivity() {
taskSubDescEditText = findViewById(R.id.tasksubDescEditText)
patientIdEditText = findViewById(R.id.taskPatientIdEditText)
- priorityRadioGroup.setOnCheckedChangeListener { _, checkedId ->
- taskPriority =
- when (checkedId) {
- else -> Priority.MEDIUM
- }
- }
-
val submitButton: Button = findViewById(R.id.newTaskSubmitButton)
submitButton.setOnClickListener {
- showSaveDialog()
+ // ADDED: Validate input before save
+ if (validateInputs()) {
+ showSaveDialog()
+ }
}
val customHeader: CustomHeader = findViewById(R.id.taskCustomHeader)
@@ -56,15 +50,39 @@ class TaskAddActivity : AppCompatActivity() {
}
}
+ // ADDED: Basic validation to improve task creation flow
+ private fun validateInputs(): Boolean {
+ val patientId = patientIdEditText.text.toString().trim()
+ val taskDescription = taskDescriptionEditText.text.toString().trim()
+
+ if (patientId.isEmpty()) {
+ patientIdEditText.error = "Patient ID is required"
+ patientIdEditText.requestFocus()
+ return false
+ }
+
+ if (taskDescription.isEmpty()) {
+ taskDescriptionEditText.error = "Task description is required"
+ taskDescriptionEditText.requestFocus()
+ return false
+ }
+
+ return true
+ }
+
private fun showSaveDialog() {
val builder = AlertDialog.Builder(this)
builder.setTitle(getString(R.string.saving_changes))
+ // ADDED: Clearer confirmation message
+ builder.setMessage("Do you want to save this task?")
builder.setPositiveButton(getString(R.string.yes)) { _, _ -> saveInFirebase() }
builder.setNegativeButton(getString(R.string.no), null)
val dialog = builder.create()
dialog.setOnShowListener {
- dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(resources.getColor(R.color.colorGreen))
- dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(resources.getColor(R.color.colorRed))
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE)
+ .setTextColor(resources.getColor(R.color.colorGreen))
+ dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
+ .setTextColor(resources.getColor(R.color.colorRed))
}
dialog.show()
}
@@ -76,12 +94,22 @@ class TaskAddActivity : AppCompatActivity() {
val patientId = patientIdEditText.text.toString().trim()
val taskDescription = taskDescriptionEditText.text.toString().trim()
val taskSubDesc = taskSubDescEditText.text.toString().trim()
- val assignedNurse = assignedNurseEditText.text.toString().trim()
+
+ // ADDED: No nurse input exists in current UI, so default value is used
+ val assignedNurse = "Not Assigned"
+
+ // IMPROVED: Merge sub description with main description when provided
+ val finalDescription =
+ if (taskSubDesc.isNotEmpty()) {
+ "$taskDescription - $taskSubDesc"
+ } else {
+ taskDescription
+ }
val newTask =
Task(
taskId = "",
- description = taskDescription,
+ description = finalDescription,
assignedNurse = assignedNurse,
priority = taskPriority,
patientId = patientId,
@@ -90,22 +118,34 @@ class TaskAddActivity : AppCompatActivity() {
val taskId = caretakerTaskRef.push().key ?: ""
newTask.taskId = taskId
+ // ADDED: Prevent repeated taps during save
+ val submitButton: Button = findViewById(R.id.newTaskSubmitButton)
+ submitButton.isEnabled = false
+
caretakerTaskRef.child(taskId).setValue(newTask).addOnCompleteListener { task ->
if (task.isSuccessful) {
updatePatientTasks(taskId)
- finish()
+
+ // IMPROVED: Also save to nurse tasks and show feedback
+ val nurseTaskRef = databaseRef.child("nurse_tasks")
+ nurseTaskRef.child(taskId).setValue(newTask).addOnCompleteListener { nurseTask ->
+ if (nurseTask.isSuccessful) {
+ Toast.makeText(this, "Task saved successfully", Toast.LENGTH_SHORT).show()
+ finish()
+ } else {
+ Toast.makeText(this, "Task saved partially", Toast.LENGTH_SHORT).show()
+ submitButton.isEnabled = true
+ }
+ }
} else {
- // Handle the error
+ Toast.makeText(this, "Failed to save task", Toast.LENGTH_SHORT).show()
+ submitButton.isEnabled = true
}
}
-
- // Save under nurse tasks as well
- val nurseTaskRef = databaseRef.child("nurse_tasks")
- nurseTaskRef.child(taskId).setValue(newTask)
}
private fun updatePatientTasks(taskId: String) {
val patientTasksRef = FirebaseDatabase.getInstance().reference.child("patient_tasks")
patientTasksRef.child(taskId).setValue(true)
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/general/TaskDetailActivity.kt b/app/src/main/java/deakin/gopher/guardian/view/general/TaskDetailActivity.kt
index 962ede6c2..f92781282 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/general/TaskDetailActivity.kt
+++ b/app/src/main/java/deakin/gopher/guardian/view/general/TaskDetailActivity.kt
@@ -14,97 +14,147 @@ import deakin.gopher.guardian.R
import deakin.gopher.guardian.model.Task
class TaskDetailActivity : AppCompatActivity() {
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_detail)
- var taskDescriptionTextView: TextView = findViewById(R.id.task_detail_description_text_view)
- var taskAssignedNurseTextView: TextView = findViewById(R.id.task_text_view_nurse_name)
- var taskPriorityTextView: TextView = findViewById(R.id.task_text_view_priority)
- var completeButton: Button = findViewById(R.id.task_button_mark_complete)
- var backButton: Button = findViewById(R.id.task_detail_back_button)
- var deleteButton: Button = findViewById(R.id.task_button_mark_delete)
- var incompleteButton: Button = findViewById(R.id.task_button_mark_incomplete)
+
+ val taskDescriptionTextView: TextView = findViewById(R.id.task_detail_description_text_view)
+ val taskAssignedNurseTextView: TextView = findViewById(R.id.task_text_view_nurse_name)
+ val taskPriorityTextView: TextView = findViewById(R.id.task_text_view_priority)
+
+ val completeButton: Button = findViewById(R.id.task_button_mark_complete)
+ val incompleteButton: Button = findViewById(R.id.task_button_mark_incomplete)
+ val deleteButton: Button = findViewById(R.id.task_button_mark_delete)
+ val backButton: Button = findViewById(R.id.task_detail_back_button)
+
val taskId = intent.getStringExtra("taskId")
- if (taskId != null) {
- val taskRef = FirebaseDatabase.getInstance().getReference("nurse-tasks").child(taskId)
- taskRef.addListenerForSingleValueEvent(
- object : ValueEventListener {
- override fun onDataChange(dataSnapshot: DataSnapshot) {
- if (dataSnapshot.exists()) {
- val task =
- dataSnapshot.getValue(
- Task::class.java,
- )
- if (task != null) {
- var textdesc = getString(R.string.task_description_prefix) + " " + task.description
- var textnur = getString(R.string.assigned_nurse_prefix) + " " + task.assignedNurse
- var textprior = getString(R.string.priority_prefix) + " " + task.priority.toString()
-
- taskDescriptionTextView.setText(textdesc)
- taskAssignedNurseTextView.setText(textnur)
- taskPriorityTextView.setText(textprior)
-
- if (task.completed) {
- completeButton.visibility = View.GONE
- incompleteButton.visibility = View.VISIBLE
- } else {
- incompleteButton.visibility = View.GONE
- completeButton.visibility = View.VISIBLE
- }
- }
- }
- }
- override fun onCancelled(databaseError: DatabaseError) {
+ // ADDED: Handle missing taskId (prevents crash / blank screen)
+ if (taskId == null) {
+ Toast.makeText(this, "Task not found", Toast.LENGTH_SHORT).show()
+ finish()
+ return
+ }
+
+ val taskRef = FirebaseDatabase.getInstance().getReference("nurse-tasks").child(taskId)
+
+ // ADDED: Show loading state (basic UX improvement)
+ taskDescriptionTextView.text = "Loading..."
+ taskAssignedNurseTextView.text = ""
+ taskPriorityTextView.text = ""
+
+ taskRef.addListenerForSingleValueEvent(
+ object : ValueEventListener {
+ override fun onDataChange(dataSnapshot: DataSnapshot) {
+
+ // ADDED: Handle empty snapshot (task deleted or missing)
+ if (!dataSnapshot.exists()) {
Toast.makeText(
this@TaskDetailActivity,
- databaseError.toString(),
- Toast.LENGTH_SHORT,
+ "Task not found",
+ Toast.LENGTH_SHORT
).show()
- }
- },
- )
-
- fun markAsCompleted() {
- val taskRef = FirebaseDatabase.getInstance().getReference("nurse-tasks").child(taskId)
- taskRef.child("completed").setValue(true)
- Toast.makeText(this@TaskDetailActivity, "Task marked as completed", Toast.LENGTH_SHORT).show()
- completeButton.visibility = View.GONE
- incompleteButton.visibility = View.VISIBLE
- }
-
- fun markAsIncomplete() {
- val taskRef = FirebaseDatabase.getInstance().getReference("nurse-tasks").child(taskId)
- taskRef.child("completed").setValue(false)
- Toast.makeText(this@TaskDetailActivity, "Task marked as incomplete", Toast.LENGTH_SHORT).show()
- incompleteButton.visibility = View.GONE
- completeButton.visibility = View.VISIBLE
- }
-
- fun deleteTask() {
- val taskRef =
- FirebaseDatabase.getInstance().getReference("nurse-tasks").child(taskId)
- taskRef.removeValue()
- .addOnSuccessListener {
- Toast.makeText(this, "Task deleted", Toast.LENGTH_SHORT).show()
finish()
+ return
}
- .addOnFailureListener {
- Toast.makeText(this, "Failed to delete task", Toast.LENGTH_SHORT).show()
+
+ val task = dataSnapshot.getValue(Task::class.java)
+
+ if (task != null) {
+
+ val textdesc =
+ getString(R.string.task_description_prefix) + " " + task.description
+ val textnur =
+ getString(R.string.assigned_nurse_prefix) + " " + task.assignedNurse
+ val textprior =
+ getString(R.string.priority_prefix) + " " + task.priority.toString()
+
+ taskDescriptionTextView.text = textdesc
+ taskAssignedNurseTextView.text = textnur
+ taskPriorityTextView.text = textprior
+
+ // IMPROVED: Clearer button state handling
+ if (task.completed) {
+ completeButton.visibility = View.GONE
+ incompleteButton.visibility = View.VISIBLE
+ } else {
+ incompleteButton.visibility = View.GONE
+ completeButton.visibility = View.VISIBLE
+ }
}
- }
- completeButton.setOnClickListener {
- markAsCompleted()
- }
- incompleteButton.setOnClickListener {
- markAsIncomplete()
- }
- backButton.setOnClickListener {
- finish()
- }
- deleteButton.setOnClickListener {
- deleteTask()
- }
+ }
+
+ override fun onCancelled(databaseError: DatabaseError) {
+ // IMPROVED: Better error message
+ Toast.makeText(
+ this@TaskDetailActivity,
+ "Failed to load task",
+ Toast.LENGTH_SHORT
+ ).show()
+ }
+ },
+ )
+
+ // IMPROVED: Disable button during action to prevent multiple clicks
+ fun markAsCompleted() {
+ completeButton.isEnabled = false
+
+ taskRef.child("completed").setValue(true)
+ .addOnSuccessListener {
+ Toast.makeText(this, "Task marked as completed", Toast.LENGTH_SHORT).show()
+ completeButton.visibility = View.GONE
+ incompleteButton.visibility = View.VISIBLE
+ }
+ .addOnFailureListener {
+ Toast.makeText(this, "Failed to update task", Toast.LENGTH_SHORT).show()
+ completeButton.isEnabled = true
+ }
+ }
+
+ fun markAsIncomplete() {
+ incompleteButton.isEnabled = false
+
+ taskRef.child("completed").setValue(false)
+ .addOnSuccessListener {
+ Toast.makeText(this, "Task marked as incomplete", Toast.LENGTH_SHORT).show()
+ incompleteButton.visibility = View.GONE
+ completeButton.visibility = View.VISIBLE
+ }
+ .addOnFailureListener {
+ Toast.makeText(this, "Failed to update task", Toast.LENGTH_SHORT).show()
+ incompleteButton.isEnabled = true
+ }
+ }
+
+ fun deleteTask() {
+ deleteButton.isEnabled = false
+
+ taskRef.removeValue()
+ .addOnSuccessListener {
+ Toast.makeText(this, "Task deleted", Toast.LENGTH_SHORT).show()
+ finish()
+ }
+ .addOnFailureListener {
+ Toast.makeText(this, "Failed to delete task", Toast.LENGTH_SHORT).show()
+ deleteButton.isEnabled = true
+ }
+ }
+
+ completeButton.setOnClickListener {
+ markAsCompleted()
+ }
+
+ incompleteButton.setOnClickListener {
+ markAsIncomplete()
+ }
+
+ deleteButton.setOnClickListener {
+ deleteTask()
+ }
+
+ backButton.setOnClickListener {
+ finish()
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/general/TasksListActivity.kt b/app/src/main/java/deakin/gopher/guardian/view/general/TasksListActivity.kt
index 0661d6955..83621ea07 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/general/TasksListActivity.kt
+++ b/app/src/main/java/deakin/gopher/guardian/view/general/TasksListActivity.kt
@@ -3,10 +3,12 @@ package deakin.gopher.guardian.view.general
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
+import android.view.View
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.SearchView
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.view.GravityCompat
@@ -31,39 +33,51 @@ class TasksListActivity : AppCompatActivity() {
private var overviewCardview: CardView? = null
private lateinit var plusButton: ImageButton
+ // ADDED: Keep a reference to the Firebase listener to avoid duplicate listeners
+ private var taskValueEventListener: ValueEventListener? = null
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tasks_list)
+
val navigationView: NavigationView = findViewById(R.id.nav_view)
val taskListMenuBtn: ImageView = findViewById(R.id.task_list_manu_button)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
plusButton = findViewById(R.id.imageView62)
navigationView.setItemIconTintList(null)
- taskListMenuBtn.setOnClickListener {
- drawerLayout.openDrawer(GravityCompat.START)
- navigationView.setNavigationItemSelectedListener { menuItem: MenuItem ->
- val id = menuItem.itemId
- when (id) {
- R.id.nav_home ->
- startActivity(
- Intent(this@TasksListActivity, Homepage4caretaker::class.java),
- )
-// R.id.nav_settings -> startActivity(
-// Intent(this@TasksListActivity, Setting::class.java)
-// )
- R.id.add_task ->
- startActivity(
- Intent(this@TasksListActivity, TaskAddActivity::class.java),
- )
- R.id.nav_signout -> {
- FirebaseAuth.getInstance().signOut()
- startActivity(Intent(this@TasksListActivity, LoginActivity::class.java))
- finish()
- }
+
+ // FIXED: Navigation item listener moved outside menu button click
+ // This prevents the listener from being attached again every time the menu button is pressed
+ navigationView.setNavigationItemSelectedListener { menuItem: MenuItem ->
+ val id = menuItem.itemId
+ when (id) {
+ R.id.nav_home ->
+ startActivity(
+ Intent(this@TasksListActivity, Homepage4caretaker::class.java),
+ )
+
+// R.id.nav_settings -> startActivity(
+// Intent(this@TasksListActivity, Setting::class.java)
+// )
+
+ R.id.add_task ->
+ startActivity(
+ Intent(this@TasksListActivity, TaskAddActivity::class.java),
+ )
+
+ R.id.nav_signout -> {
+ FirebaseAuth.getInstance().signOut()
+ startActivity(Intent(this@TasksListActivity, LoginActivity::class.java))
+ finish()
}
- true
}
+ true
+ }
+
+ // SIMPLIFIED: Menu button only opens the drawer
+ taskListMenuBtn.setOnClickListener {
+ drawerLayout.openDrawer(GravityCompat.START)
}
plusButton.setOnClickListener {
@@ -74,6 +88,7 @@ class TasksListActivity : AppCompatActivity() {
overviewCardview = findViewById(R.id.task_list_task_overview)
val taskSearchView: SearchView = findViewById(R.id.task_list_searchView)
val addTaskButton: Button = findViewById(R.id.add_task_button)
+
addTaskButton.setOnClickListener {
NavigationService(this).onLaunchTaskCreator()
}
@@ -108,6 +123,8 @@ class TasksListActivity : AppCompatActivity() {
.endAt(s + "\uf8ff")
.limitToFirst(10)
}
+
+ // REFRESH: Reload Firebase data when search text changes
fetchDataFromFirebase()
return true
}
@@ -116,23 +133,52 @@ class TasksListActivity : AppCompatActivity() {
}
private fun fetchDataFromFirebase() {
- query?.addValueEventListener(
+ // ADDED: Remove previous listener before attaching a new one
+ // This avoids duplicate callbacks when search text changes
+ taskValueEventListener?.let { listener ->
+ query?.removeEventListener(listener)
+ }
+
+ taskValueEventListener =
object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val taskList = mutableListOf()
+
for (taskSnapshot in dataSnapshot.children) {
val task = taskSnapshot.getValue(Task::class.java)
if (task != null) {
taskList.add(task)
}
}
+
taskListAdapter?.updateTaskList(taskList)
+
+ // ADDED: Basic empty-state handling using existing CardView
+ if (taskList.isEmpty()) {
+ overviewCardview?.visibility = View.GONE
+ } else {
+ overviewCardview?.visibility = View.VISIBLE
+ }
}
override fun onCancelled(databaseError: DatabaseError) {
- // Handle possible errors.
+ // ADDED: Show simple error feedback to improve user experience
+ Toast.makeText(
+ this@TasksListActivity,
+ "Failed to load tasks: ${databaseError.message}",
+ Toast.LENGTH_SHORT,
+ ).show()
}
- },
- )
+ }
+
+ query?.addValueEventListener(taskValueEventListener!!)
+ }
+
+ // ADDED: Remove listener when activity is destroyed to improve stability
+ override fun onDestroy() {
+ super.onDestroy()
+ taskValueEventListener?.let { listener ->
+ query?.removeEventListener(listener)
+ }
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanActivity.java b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanActivity.java
index 5d97ac573..e47bee051 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanActivity.java
+++ b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanActivity.java
@@ -6,6 +6,7 @@
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
+import android.widget.Toast; // ADDED
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
@@ -22,295 +23,333 @@
import java.util.HashMap;
public class CarePlanActivity extends AppCompatActivity {
- final HashMap supportRequirementsCheckBox = new HashMap<>();
- final HashMap drinkLikesCheckBox = new HashMap<>();
- final HashMap painCheckBox = new HashMap<>();
- final HashMap behavioralManagementCheckBox = new HashMap<>();
-
- RadioGroup carePlanTypeRadioGroup;
- HashMap carePlanTypesRadioButtons = new HashMap<>();
-
- RadioGroup nutritionRadioGroup;
- HashMap nutritionRadioButtons = new HashMap<>();
-
- RadioGroup dietTimeRadioGroup;
- HashMap dietTimeRadioButtons = new HashMap<>();
-
- RadioGroup sleepPatternRadioGroup;
- HashMap sleepPatternRadioButtons = new HashMap<>();
-
- RadioGroup painScoreRadioGroup;
- HashMap painScoreRadioButtons = new HashMap<>();
-
- Button submitButton;
- ImageView carePlanMenuButton;
- DatabaseReference carePlanRef;
- String patientId;
-
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- patientId = getIntent().getStringExtra("patientId");
- setContentView(R.layout.activity_care_plan);
-
- submitButton = findViewById(R.id.carePlanSubmitButton);
-
- final NavigationView navigationView = findViewById(R.id.nav_view);
- carePlanMenuButton = findViewById(R.id.menuButton11);
- final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
- navigationView.setItemIconTintList(null);
-
- carePlanMenuButton.setOnClickListener(
- v -> {
- drawerLayout.openDrawer(GravityCompat.START);
- });
-
- // careplan type
- carePlanTypeRadioGroup = findViewById(R.id.carePlanTypeRGroup);
- carePlanTypesRadioButtons.put((RadioButton) findViewById(R.id.radioButton2), "Home");
- carePlanTypesRadioButtons.put((RadioButton) findViewById(R.id.radioButton), "Hospital");
-
- nutritionRadioGroup = findViewById(R.id.nutritionHydrationRGroup);
- nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton6), "Yes");
- nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton7), "No");
- nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton8), "NA");
-
- dietTimeRadioGroup = findViewById((R.id.dietTimingRGroup));
- dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton9), "8AM-BR");
- dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton5), "12PM-LN");
- dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton10), "6PM-DN");
-
- sleepPatternRadioGroup = findViewById(R.id.sleepPatternsRGroup);
- sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton61), "10PM-6AM");
- sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton71), "8PM-4AM");
- sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton81), "11PM-7AM");
-
- painScoreRadioGroup = findViewById(R.id.ratingGroup);
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton21)), "1");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton22)), "2");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton23)), "3");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton24)), "4");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton25)), "5");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton26)), "6");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton27)), "7");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton28)), "8");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton29)), "9");
- painScoreRadioButtons.put((RadioButton) findViewById((R.id.radioButton30)), "10");
-
- // support requirements
- supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.selfCareCheckBox), "Self Care");
- supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.walkingCheckBox), "Walking");
- supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.activitiesCheckBox), "Activities");
- supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.bathroomCheckBox), "Bathroom");
- supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.shoppingCheckBox), "Shopping");
-
- // drinks
- drinkLikesCheckBox.put((CheckBox) findViewById(R.id.coffeeCheckBox), "Coffee");
- drinkLikesCheckBox.put((CheckBox) findViewById(R.id.teaCheckBox), "Tea");
- drinkLikesCheckBox.put((CheckBox) findViewById(R.id.waterCheckBox), "Water");
-
- // pain
- painCheckBox.put((CheckBox) findViewById(R.id.chronicCheckBox), "Chronic");
- painCheckBox.put((CheckBox) findViewById(R.id.massageRequiredCheckBox), "Massage Required");
- painCheckBox.put((CheckBox) findViewById(R.id.pillowSupportCheckBox), "Pillow Support");
- painCheckBox.put((CheckBox) findViewById(R.id.heatPackCheckBox), "Heat Pack");
- painCheckBox.put((CheckBox) findViewById(R.id.NAcheckBox), "NA");
-
- // behavior
- behavioralManagementCheckBox.put(
- (CheckBox) findViewById(R.id.dollTherapyCheckBox), "Doll Therapy");
- behavioralManagementCheckBox.put(
- (CheckBox) findViewById(R.id.petTherapyCheckBox), "Pet Therapy");
- behavioralManagementCheckBox.put(
- (CheckBox) findViewById(R.id.dementiaCheckBox), "Dementia Management");
- behavioralManagementCheckBox.put(
- (CheckBox) findViewById(R.id.lightsOnBedroomCB), "Lights on Bedroom");
- behavioralManagementCheckBox.put(
- (CheckBox) findViewById(R.id.lightsOnBathroomCB), "Lights on Bathroom");
-
- // Firebase initialization
- FirebaseDatabase database = FirebaseDatabase.getInstance();
- carePlanRef = database.getReference("careplan");
- // Load care plan summary data from Firebase
- if (!"".equals(patientId) && null != patientId) {
- loadCarePlanDataForPatient(patientId);
+ final HashMap supportRequirementsCheckBox = new HashMap<>();
+ final HashMap drinkLikesCheckBox = new HashMap<>();
+ final HashMap painCheckBox = new HashMap<>();
+ final HashMap behavioralManagementCheckBox = new HashMap<>();
+
+ RadioGroup carePlanTypeRadioGroup;
+ HashMap carePlanTypesRadioButtons = new HashMap<>();
+
+ RadioGroup nutritionRadioGroup;
+ HashMap nutritionRadioButtons = new HashMap<>();
+
+ RadioGroup dietTimeRadioGroup;
+ HashMap dietTimeRadioButtons = new HashMap<>();
+
+ RadioGroup sleepPatternRadioGroup;
+ HashMap sleepPatternRadioButtons = new HashMap<>();
+
+ RadioGroup painScoreRadioGroup;
+ HashMap painScoreRadioButtons = new HashMap<>();
+
+ Button submitButton;
+ ImageView carePlanMenuButton;
+ DatabaseReference carePlanRef;
+ String patientId;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ patientId = getIntent().getStringExtra("patientId");
+
+ // ADDED: Prevent invalid screen state if patientId is missing
+ if (patientId == null || patientId.isEmpty()) {
+ Toast.makeText(this, "Invalid patient", Toast.LENGTH_SHORT).show();
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.activity_care_plan);
+
+ submitButton = findViewById(R.id.carePlanSubmitButton);
+
+ final NavigationView navigationView = findViewById(R.id.nav_view);
+ carePlanMenuButton = findViewById(R.id.menuButton11);
+ final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
+ navigationView.setItemIconTintList(null);
+
+ carePlanMenuButton.setOnClickListener(
+ v -> {
+ drawerLayout.openDrawer(GravityCompat.START);
+ });
+
+ // careplan type
+ carePlanTypeRadioGroup = findViewById(R.id.carePlanTypeRGroup);
+ carePlanTypesRadioButtons.put((RadioButton) findViewById(R.id.radioButton2), "Home");
+ carePlanTypesRadioButtons.put((RadioButton) findViewById(R.id.radioButton), "Hospital");
+
+ nutritionRadioGroup = findViewById(R.id.nutritionHydrationRGroup);
+ nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton6), "Yes");
+ nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton7), "No");
+ nutritionRadioButtons.put((RadioButton) findViewById(R.id.radioButton8), "NA");
+
+ dietTimeRadioGroup = findViewById(R.id.dietTimingRGroup);
+ dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton9), "8AM-BR");
+ dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton5), "12PM-LN");
+ dietTimeRadioButtons.put((RadioButton) findViewById(R.id.radioButton10), "6PM-DN");
+
+ sleepPatternRadioGroup = findViewById(R.id.sleepPatternsRGroup);
+ sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton61), "10PM-6AM");
+ sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton71), "8PM-4AM");
+ sleepPatternRadioButtons.put((RadioButton) findViewById(R.id.radioButton81), "11PM-7AM");
+
+ painScoreRadioGroup = findViewById(R.id.ratingGroup);
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton21), "1");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton22), "2");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton23), "3");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton24), "4");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton25), "5");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton26), "6");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton27), "7");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton28), "8");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton29), "9");
+ painScoreRadioButtons.put((RadioButton) findViewById(R.id.radioButton30), "10");
+
+ // support requirements
+ supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.selfCareCheckBox), "Self Care");
+ supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.walkingCheckBox), "Walking");
+ supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.activitiesCheckBox), "Activities");
+ supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.bathroomCheckBox), "Bathroom");
+ supportRequirementsCheckBox.put((CheckBox) findViewById(R.id.shoppingCheckBox), "Shopping");
+
+ // drinks
+ drinkLikesCheckBox.put((CheckBox) findViewById(R.id.coffeeCheckBox), "Coffee");
+ drinkLikesCheckBox.put((CheckBox) findViewById(R.id.teaCheckBox), "Tea");
+ drinkLikesCheckBox.put((CheckBox) findViewById(R.id.waterCheckBox), "Water");
+
+ // pain
+ painCheckBox.put((CheckBox) findViewById(R.id.chronicCheckBox), "Chronic");
+ painCheckBox.put((CheckBox) findViewById(R.id.massageRequiredCheckBox), "Massage Required");
+ painCheckBox.put((CheckBox) findViewById(R.id.pillowSupportCheckBox), "Pillow Support");
+ painCheckBox.put((CheckBox) findViewById(R.id.heatPackCheckBox), "Heat Pack");
+ painCheckBox.put((CheckBox) findViewById(R.id.NAcheckBox), "NA");
+
+ // behavior
+ behavioralManagementCheckBox.put(
+ (CheckBox) findViewById(R.id.dollTherapyCheckBox), "Doll Therapy");
+ behavioralManagementCheckBox.put(
+ (CheckBox) findViewById(R.id.petTherapyCheckBox), "Pet Therapy");
+ behavioralManagementCheckBox.put(
+ (CheckBox) findViewById(R.id.dementiaCheckBox), "Dementia Management");
+ behavioralManagementCheckBox.put(
+ (CheckBox) findViewById(R.id.lightsOnBedroomCB), "Lights on Bedroom");
+ behavioralManagementCheckBox.put(
+ (CheckBox) findViewById(R.id.lightsOnBathroomCB), "Lights on Bathroom");
+
+ // Firebase initialization
+ FirebaseDatabase database = FirebaseDatabase.getInstance();
+ carePlanRef = database.getReference("careplan");
+
+ // Load care plan summary data from Firebase
+ loadCarePlanDataForPatient(patientId);
+
+ submitButton.setOnClickListener(
+ v -> {
+ // ADDED: Basic validation before confirmation
+ if (!validateInputs()) {
+ return;
+ }
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
+ builder.setTitle("Saving Changes?");
+ // ADDED: Clearer confirmation message
+ builder.setMessage("Do you want to save this care plan?");
+ builder.setPositiveButton(
+ "YES",
+ (dialog, whichButton) -> {
+ CarePlan updatedCarePlan = createUpdatedCarePlan();
+
+ // ADDED: Prevent repeated taps during save
+ submitButton.setEnabled(false);
+
+ // Save the updated CarePlan to Firebase
+ saveCarePlanToFirebase(updatedCarePlan);
+ });
+ builder.setNegativeButton("No", null);
+
+ final AlertDialog dialog = builder.create();
+ dialog.setOnShowListener(
+ arg0 -> {
+ dialog
+ .getButton(AlertDialog.BUTTON_POSITIVE)
+ .setTextColor(getResources().getColor(R.color.colorGreen));
+ dialog
+ .getButton(AlertDialog.BUTTON_NEGATIVE)
+ .setTextColor(getResources().getColor(R.color.colorRed));
+ });
+ dialog.show();
+ });
}
- submitButton.setOnClickListener(
- v -> {
- final AlertDialog.Builder builder =
- new AlertDialog.Builder(v.getContext()); // new AlertDialog.Builder(this);
- builder.setTitle("Saving Changes?");
- builder.setPositiveButton(
- "YES",
- (dialog, whichButton) -> {
- CarePlan updatedCarePlan = createUpdatedCarePlan();
- // Save the updated CarePlan to Firebase
- saveCarePlanToFirebase(updatedCarePlan);
-
- // final Intent intent =
- // new Intent(getApplicationContext(),
- // CarePlanSummaryActivity.class);
- // startActivity(intent);
- });
- builder.setNegativeButton("No", null);
-
- final AlertDialog dialog = builder.create();
- dialog.setOnShowListener(
- arg0 -> {
- dialog
- .getButton(AlertDialog.BUTTON_POSITIVE)
- .setTextColor(getResources().getColor(R.color.colorGreen));
- dialog
- .getButton(AlertDialog.BUTTON_NEGATIVE)
- .setTextColor(getResources().getColor(R.color.colorRed));
- });
- dialog.show();
- });
- }
-
- private void loadCarePlanDataForPatient(final String patientId) {
- DatabaseReference patientRef = carePlanRef.child(patientId);
- patientRef.addListenerForSingleValueEvent(
- new ValueEventListener() {
- @Override
- public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
- if (dataSnapshot.exists()) {
- CarePlan carePlan = dataSnapshot.getValue(CarePlan.class);
- if (carePlan != null) {
-
- String carePlanType = carePlan.carePlanType;
- selectRadioButton(carePlanTypeRadioGroup, carePlanTypesRadioButtons, carePlanType);
-
- String nutriHydration = carePlan.nutritionHydration;
- selectRadioButton(nutritionRadioGroup, nutritionRadioButtons, nutriHydration);
-
- String dietTime = carePlan.dietTimings;
- selectRadioButton(dietTimeRadioGroup, dietTimeRadioButtons, dietTime);
-
- String sleepPattern = carePlan.sleepPattern;
- selectRadioButton(sleepPatternRadioGroup, sleepPatternRadioButtons, sleepPattern);
-
- String painScore = String.valueOf(carePlan.painScore);
- selectRadioButton(painScoreRadioGroup, painScoreRadioButtons, painScore);
-
- // Pre-fill support requirements checkboxes
- for (CheckBox checkBox : supportRequirementsCheckBox.keySet()) {
- String requirement = supportRequirementsCheckBox.get(checkBox);
- if (carePlan.supportRequirement.contains(requirement)) {
- checkBox.setChecked(true);
- }
- }
-
- // Pre-fill drink likes checkboxes
- for (CheckBox checkBox : drinkLikesCheckBox.keySet()) {
- String drink = drinkLikesCheckBox.get(checkBox);
- if (carePlan.drinkLikings.contains(drink)) {
- checkBox.setChecked(true);
- }
- }
-
- // Pre-fill pain checkboxes
- for (CheckBox checkBox : painCheckBox.keySet()) {
- String pain = painCheckBox.get(checkBox);
- if (carePlan.painCategories.contains(pain)) {
- checkBox.setChecked(true);
- }
- }
-
- // Pre-fill behavioral management checkboxes
- for (CheckBox checkBox : behavioralManagementCheckBox.keySet()) {
- String behavior = behavioralManagementCheckBox.get(checkBox);
- if (carePlan.behavioralManagement.contains(behavior)) {
- checkBox.setChecked(true);
- }
- }
- }
- }
- }
-
- @Override
- public void onCancelled(@NonNull DatabaseError error) {
- // Handle error
- }
- });
- }
-
- private String getSelectedRadioButtonValue(
- RadioGroup radioGroup, HashMap radioButtons) {
- int selectedId = radioGroup.getCheckedRadioButtonId();
- if (selectedId != -1) {
- RadioButton radioButton = findViewById(selectedId);
- return radioButtons.get(radioButton);
+ // ADDED: Simple validation to improve form flow
+ private boolean validateInputs() {
+ if (carePlanTypeRadioGroup.getCheckedRadioButtonId() == -1) {
+ Toast.makeText(this, "Please select care plan type", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ return true;
}
- return null;
- }
-
- private void selectRadioButton(
- RadioGroup radioGroup, HashMap radioButtons, String selectedValue) {
- for (RadioButton radioButton : radioButtons.keySet()) {
- if (radioButtons.get(radioButton).equals(selectedValue)) {
- radioGroup.check(radioButton.getId());
- break;
- }
+
+ private void loadCarePlanDataForPatient(final String patientId) {
+ DatabaseReference patientRef = carePlanRef.child(patientId);
+ patientRef.addListenerForSingleValueEvent(
+ new ValueEventListener() {
+ @Override
+ public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
+ if (dataSnapshot.exists()) {
+ CarePlan carePlan = dataSnapshot.getValue(CarePlan.class);
+ if (carePlan != null) {
+
+ String carePlanType = carePlan.carePlanType;
+ selectRadioButton(carePlanTypeRadioGroup, carePlanTypesRadioButtons, carePlanType);
+
+ String nutriHydration = carePlan.nutritionHydration;
+ selectRadioButton(nutritionRadioGroup, nutritionRadioButtons, nutriHydration);
+
+ String dietTime = carePlan.dietTimings;
+ selectRadioButton(dietTimeRadioGroup, dietTimeRadioButtons, dietTime);
+
+ String sleepPattern = carePlan.sleepPattern;
+ selectRadioButton(sleepPatternRadioGroup, sleepPatternRadioButtons, sleepPattern);
+
+ String painScore = String.valueOf(carePlan.painScore);
+ selectRadioButton(painScoreRadioGroup, painScoreRadioButtons, painScore);
+
+ // Pre-fill support requirements checkboxes
+ for (CheckBox checkBox : supportRequirementsCheckBox.keySet()) {
+ String requirement = supportRequirementsCheckBox.get(checkBox);
+ if (carePlan.supportRequirement != null
+ && carePlan.supportRequirement.contains(requirement)) {
+ checkBox.setChecked(true);
+ }
+ }
+
+ // Pre-fill drink likes checkboxes
+ for (CheckBox checkBox : drinkLikesCheckBox.keySet()) {
+ String drink = drinkLikesCheckBox.get(checkBox);
+ if (carePlan.drinkLikings != null && carePlan.drinkLikings.contains(drink)) {
+ checkBox.setChecked(true);
+ }
+ }
+
+ // Pre-fill pain checkboxes
+ for (CheckBox checkBox : painCheckBox.keySet()) {
+ String pain = painCheckBox.get(checkBox);
+ if (carePlan.painCategories != null && carePlan.painCategories.contains(pain)) {
+ checkBox.setChecked(true);
+ }
+ }
+
+ // Pre-fill behavioral management checkboxes
+ for (CheckBox checkBox : behavioralManagementCheckBox.keySet()) {
+ String behavior = behavioralManagementCheckBox.get(checkBox);
+ if (carePlan.behavioralManagement != null
+ && carePlan.behavioralManagement.contains(behavior)) {
+ checkBox.setChecked(true);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onCancelled(@NonNull DatabaseError error) {
+ // IMPROVED: Show error to user
+ Toast.makeText(CarePlanActivity.this, "Failed to load care plan", Toast.LENGTH_SHORT)
+ .show();
+ }
+ });
}
- }
- private CarePlan createUpdatedCarePlan() {
- CarePlan carePlan = new CarePlan();
+ private String getSelectedRadioButtonValue(
+ RadioGroup radioGroup, HashMap radioButtons) {
+ int selectedId = radioGroup.getCheckedRadioButtonId();
+ if (selectedId != -1) {
+ RadioButton radioButton = findViewById(selectedId);
+ return radioButtons.get(radioButton);
+ }
+ return null;
+ }
- // Set care plan type
- carePlan.carePlanType =
- getSelectedRadioButtonValue(carePlanTypeRadioGroup, carePlanTypesRadioButtons);
+ private void selectRadioButton(
+ RadioGroup radioGroup, HashMap radioButtons, String selectedValue) {
+ for (RadioButton radioButton : radioButtons.keySet()) {
+ if (radioButtons.get(radioButton).equals(selectedValue)) {
+ radioGroup.check(radioButton.getId());
+ break;
+ }
+ }
+ }
- // Set nutrition hydration
- carePlan.nutritionHydration =
- getSelectedRadioButtonValue(nutritionRadioGroup, nutritionRadioButtons);
+ private CarePlan createUpdatedCarePlan() {
+ CarePlan carePlan = new CarePlan();
- // Set diet timings
- carePlan.dietTimings = getSelectedRadioButtonValue(dietTimeRadioGroup, dietTimeRadioButtons);
+ // Set care plan type
+ carePlan.carePlanType =
+ getSelectedRadioButtonValue(carePlanTypeRadioGroup, carePlanTypesRadioButtons);
- // Set sleep pattern
- carePlan.sleepPattern =
- getSelectedRadioButtonValue(sleepPatternRadioGroup, sleepPatternRadioButtons);
+ // Set nutrition hydration
+ carePlan.nutritionHydration =
+ getSelectedRadioButtonValue(nutritionRadioGroup, nutritionRadioButtons);
- // Set pain score
- String painScore = getSelectedRadioButtonValue(painScoreRadioGroup, painScoreRadioButtons);
- if (painScore != null) {
- carePlan.painScore = Integer.parseInt(painScore);
- }
+ // Set diet timings
+ carePlan.dietTimings = getSelectedRadioButtonValue(dietTimeRadioGroup, dietTimeRadioButtons);
- // Set support requirements checkboxes
- carePlan.supportRequirement = getCheckedItemsAsString(supportRequirementsCheckBox);
+ // Set sleep pattern
+ carePlan.sleepPattern =
+ getSelectedRadioButtonValue(sleepPatternRadioGroup, sleepPatternRadioButtons);
- // Set drink likes checkboxes
- carePlan.drinkLikings = getCheckedItemsAsString(drinkLikesCheckBox);
+ // Set pain score
+ String painScore = getSelectedRadioButtonValue(painScoreRadioGroup, painScoreRadioButtons);
+ if (painScore != null) {
+ carePlan.painScore = Integer.parseInt(painScore);
+ }
- // Set pain checkboxes
- carePlan.painCategories = getCheckedItemsAsString(painCheckBox);
+ // Set support requirements checkboxes
+ carePlan.supportRequirement = getCheckedItemsAsString(supportRequirementsCheckBox);
- // Set behavioral management checkboxes
- carePlan.behavioralManagement = getCheckedItemsAsString(behavioralManagementCheckBox);
+ // Set drink likes checkboxes
+ carePlan.drinkLikings = getCheckedItemsAsString(drinkLikesCheckBox);
- return carePlan;
- }
+ // Set pain checkboxes
+ carePlan.painCategories = getCheckedItemsAsString(painCheckBox);
- private String getCheckedItemsAsString(HashMap checkBoxHashMap) {
- StringBuilder stringBuilder = new StringBuilder();
- for (CheckBox checkBox : checkBoxHashMap.keySet()) {
- if (checkBox.isChecked()) {
- stringBuilder.append(checkBoxHashMap.get(checkBox)).append(", ");
- }
+ // Set behavioral management checkboxes
+ carePlan.behavioralManagement = getCheckedItemsAsString(behavioralManagementCheckBox);
+
+ return carePlan;
}
- // Remove trailing comma and space if any
- if (stringBuilder.length() > 0) {
- stringBuilder.setLength(stringBuilder.length() - 2);
+
+ private String getCheckedItemsAsString(HashMap checkBoxHashMap) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (CheckBox checkBox : checkBoxHashMap.keySet()) {
+ if (checkBox.isChecked()) {
+ stringBuilder.append(checkBoxHashMap.get(checkBox)).append(", ");
+ }
+ }
+ // Remove trailing comma and space if any
+ if (stringBuilder.length() > 0) {
+ stringBuilder.setLength(stringBuilder.length() - 2);
+ }
+ return stringBuilder.toString();
+ }
+
+ private void saveCarePlanToFirebase(CarePlan carePlan) {
+ // IMPROVED: Show success/failure feedback and re-enable button if needed
+ carePlanRef
+ .child(patientId)
+ .setValue(carePlan)
+ .addOnSuccessListener(
+ unused -> {
+ Toast.makeText(this, "Care plan saved successfully", Toast.LENGTH_SHORT).show();
+ finish();
+ })
+ .addOnFailureListener(
+ e -> {
+ Toast.makeText(this, "Failed to save care plan", Toast.LENGTH_SHORT).show();
+ submitButton.setEnabled(true);
+ });
}
- return stringBuilder.toString();
- }
-
- private void saveCarePlanToFirebase(CarePlan carePlan) {
- // Update care plan in Firebase
- carePlanRef.child(patientId).setValue(carePlan);
- }
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivity.java b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivity.java
index 6ceab1203..9f2a4fc85 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivity.java
+++ b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivity.java
@@ -1,7 +1,6 @@
package deakin.gopher.guardian.view.patient.careplan;
import android.annotation.SuppressLint;
-import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
@@ -12,27 +11,29 @@
import deakin.gopher.guardian.R;
public class CarePlanSummaryActivity extends AppCompatActivity {
- Button prevButton;
- ImageView carePlanSummaryMenuButton;
+ Button prevButton;
+ ImageView carePlanSummaryMenuButton;
- @SuppressLint("MissingInflatedId")
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_care_plan_summary);
- prevButton = findViewById(R.id.carePlanPrevButton);
+ @SuppressLint("MissingInflatedId")
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_care_plan_summary);
- prevButton.setOnClickListener(
- view -> startActivity(new Intent(CarePlanSummaryActivity.this, CarePlanActivity.class)));
+ prevButton = findViewById(R.id.carePlanPrevButton);
- final NavigationView navigationView = findViewById(R.id.nav_view);
- carePlanSummaryMenuButton = findViewById(R.id.menuButton);
- final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
- navigationView.setItemIconTintList(null);
+ // IMPROVED: Go back to previous screen instead of creating a new CarePlanActivity
+ prevButton.setOnClickListener(view -> finish());
- carePlanSummaryMenuButton.setOnClickListener(
- v -> {
- drawerLayout.openDrawer(GravityCompat.START);
- });
- }
-}
+ final NavigationView navigationView = findViewById(R.id.nav_view);
+ carePlanSummaryMenuButton = findViewById(R.id.menuButton);
+ final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
+ navigationView.setItemIconTintList(null);
+
+ // KEPT: Drawer open interaction
+ carePlanSummaryMenuButton.setOnClickListener(
+ v -> {
+ drawerLayout.openDrawer(GravityCompat.START);
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivityFragment.java b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivityFragment.java
index 2740d787b..88810c85e 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivityFragment.java
+++ b/app/src/main/java/deakin/gopher/guardian/view/patient/careplan/CarePlanSummaryActivityFragment.java
@@ -2,6 +2,7 @@
import android.content.Intent;
import android.os.Bundle;
+import android.text.TextUtils; // ADDED
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,6 +10,7 @@
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
+import android.widget.Toast; // ADDED
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
@@ -21,108 +23,134 @@
import deakin.gopher.guardian.model.CarePlan;
public class CarePlanSummaryActivityFragment extends Fragment {
- Button prevButton;
- Button editButton;
- ImageView carePlanSummaryMenuButton;
-
- // Firebase
- DatabaseReference carePlanRef;
-
- TextView carePlanSummaryTextView;
- TextView carePlanNutHyd;
- TextView suppReq;
- TextView dietTime;
- TextView drinkLike;
- TextView sleepPat;
- TextView pain;
- TextView behaveMng;
- RatingBar ratingBar;
- String patientId;
-
- View view;
-
- public CarePlanSummaryActivityFragment(final String patientId) {
- this.patientId = patientId;
- }
-
- @Nullable
- @Override
- public View onCreateView(
- @NonNull LayoutInflater inflater,
- @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
-
- view = inflater.inflate(R.layout.fragment_careplan_summary, container, false);
-
- editButton = view.findViewById(R.id.save);
- carePlanSummaryTextView = view.findViewById(R.id.carePlanSummary);
- carePlanNutHyd = view.findViewById(R.id.nutritionHydrationSummary);
- suppReq = view.findViewById(R.id.supportReqSummary1);
- dietTime = view.findViewById(R.id.dietTimingSummary);
- drinkLike = view.findViewById(R.id.drinkLikesSummary);
- sleepPat = view.findViewById(R.id.sleepPatternSummary);
- pain = view.findViewById(R.id.painSummary);
- ratingBar = view.findViewById(R.id.painRatingBarSummary);
- behaveMng = view.findViewById(R.id.behaviouralManagement);
-
- // Set onClickListener for editButton
- editButton.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Open CarePlanActivity
- final CarePlanActivity carePlanActivity = new CarePlanActivity();
- final Intent intent = new Intent(getActivity(), carePlanActivity.getClass());
- intent.putExtra("patientId", patientId);
- startActivity(intent);
- }
- });
-
- // Firebase initialization
- FirebaseDatabase database = FirebaseDatabase.getInstance();
- carePlanRef = database.getReference("careplan");
- // Load care plan summary data from Firebase
- loadCarePlanDataForPatient(patientId);
- return view;
- }
-
- private void loadCarePlanDataForPatient(final String patientId) {
- DatabaseReference patientRef = carePlanRef.child(patientId);
- patientRef.addListenerForSingleValueEvent(
- new ValueEventListener() {
- @Override
- public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
- if (dataSnapshot.exists()) {
- CarePlan carePlan = dataSnapshot.getValue(CarePlan.class);
- if (carePlan != null) {
- carePlanSummaryTextView.setText(carePlan.carePlanType);
- carePlanNutHyd.setText(carePlan.nutritionHydration);
- suppReq.setText(carePlan.supportRequirement);
- dietTime.setText(carePlan.dietTimings);
- drinkLike.setText(carePlan.drinkLikings);
- sleepPat.setText(carePlan.sleepPattern);
- ratingBar.setRating((float) carePlan.painScore / 2);
- behaveMng.setText(carePlan.behavioralManagement);
- }
- } else {
- carePlanSummaryTextView.setText("Add new one");
- carePlanNutHyd.setVisibility(View.GONE);
- suppReq.setVisibility(View.GONE);
- dietTime.setVisibility(View.GONE);
- drinkLike.setVisibility(View.GONE);
- sleepPat.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onCancelled(@NonNull DatabaseError error) {
- // Handle error
- }
- });
- }
-
- // Interface to notify data load status
- private interface OnDataLoadListener {
- void onDataLoaded(boolean dataFound);
- }
-}
+ Button prevButton;
+ Button editButton;
+ ImageView carePlanSummaryMenuButton;
+
+ // Firebase
+ DatabaseReference carePlanRef;
+
+ TextView carePlanSummaryTextView;
+ TextView carePlanNutHyd;
+ TextView suppReq;
+ TextView dietTime;
+ TextView drinkLike;
+ TextView sleepPat;
+ TextView pain;
+ TextView behaveMng;
+ RatingBar ratingBar;
+ String patientId;
+
+ View view;
+
+ public CarePlanSummaryActivityFragment(final String patientId) {
+ this.patientId = patientId;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(
+ @NonNull LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+
+ view = inflater.inflate(R.layout.fragment_careplan_summary, container, false);
+
+ editButton = view.findViewById(R.id.save);
+ carePlanSummaryTextView = view.findViewById(R.id.carePlanSummary);
+ carePlanNutHyd = view.findViewById(R.id.nutritionHydrationSummary);
+ suppReq = view.findViewById(R.id.supportReqSummary1);
+ dietTime = view.findViewById(R.id.dietTimingSummary);
+ drinkLike = view.findViewById(R.id.drinkLikesSummary);
+ sleepPat = view.findViewById(R.id.sleepPatternSummary);
+ pain = view.findViewById(R.id.painSummary);
+ ratingBar = view.findViewById(R.id.painRatingBarSummary);
+ behaveMng = view.findViewById(R.id.behaviouralManagement);
+
+ // ADDED: Validate patientId before trying to load data
+ if (TextUtils.isEmpty(patientId)) {
+ Toast.makeText(getActivity(), "Invalid patient", Toast.LENGTH_SHORT).show();
+ return view;
+ }
+
+ // IMPROVED: Simplified edit navigation
+ editButton.setOnClickListener(
+ v -> {
+ Intent intent = new Intent(getActivity(), CarePlanActivity.class);
+ intent.putExtra("patientId", patientId);
+ startActivity(intent);
+ });
+
+ // Firebase initialization
+ FirebaseDatabase database = FirebaseDatabase.getInstance();
+ carePlanRef = database.getReference("careplan");
+
+ // ADDED: Basic loading state
+ carePlanSummaryTextView.setText("Loading care plan...");
+
+ // Load care plan summary data from Firebase
+ loadCarePlanDataForPatient(patientId);
+ return view;
+ }
+
+ private void loadCarePlanDataForPatient(final String patientId) {
+ DatabaseReference patientRef = carePlanRef.child(patientId);
+ patientRef.addListenerForSingleValueEvent(
+ new ValueEventListener() {
+ @Override
+ public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
+ if (dataSnapshot.exists()) {
+ CarePlan carePlan = dataSnapshot.getValue(CarePlan.class);
+ if (carePlan != null) {
+ // IMPROVED: Use fallback text for null or empty values
+ carePlanSummaryTextView.setText(getSafeText(carePlan.carePlanType));
+ carePlanNutHyd.setText(getSafeText(carePlan.nutritionHydration));
+ suppReq.setText(getSafeText(carePlan.supportRequirement));
+ dietTime.setText(getSafeText(carePlan.dietTimings));
+ drinkLike.setText(getSafeText(carePlan.drinkLikings));
+ sleepPat.setText(getSafeText(carePlan.sleepPattern));
+ pain.setText(getSafeText(carePlan.painCategories));
+ behaveMng.setText(getSafeText(carePlan.behavioralManagement));
+
+ // IMPROVED: Ensure rating is set safely
+ ratingBar.setRating((float) carePlan.painScore / 2);
+ } else {
+ showEmptyState();
+ }
+ } else {
+ showEmptyState();
+ }
+ }
+
+ @Override
+ public void onCancelled(@NonNull DatabaseError error) {
+ // ADDED: Show user-friendly error feedback
+ Toast.makeText(getActivity(), "Failed to load care plan", Toast.LENGTH_SHORT).show();
+ showEmptyState();
+ }
+ });
+ }
+
+ // ADDED: Reusable fallback for null/empty text values
+ private String getSafeText(String value) {
+ return TextUtils.isEmpty(value) ? "Not available" : value;
+ }
+
+ // ADDED: Cleaner empty state handling
+ private void showEmptyState() {
+ carePlanSummaryTextView.setText("No care plan available");
+ carePlanNutHyd.setText("Not available");
+ suppReq.setText("Not available");
+ dietTime.setText("Not available");
+ drinkLike.setText("Not available");
+ sleepPat.setText("Not available");
+ pain.setText("Not available");
+ behaveMng.setText("Not available");
+ ratingBar.setRating(0);
+ }
+
+ // Interface to notify data load status
+ private interface OnDataLoadListener {
+ void onDataLoaded(boolean dataFound);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportActivity.java b/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportActivity.java
index 44b42c62a..98e45bd29 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportActivity.java
+++ b/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportActivity.java
@@ -1,40 +1,176 @@
package deakin.gopher.guardian.view.patient.dailyreport;
+import android.content.Intent;
import android.os.Bundle;
+import android.widget.Button;
+import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.navigation.NavigationView;
import deakin.gopher.guardian.R;
+
public class DailyReportActivity extends AppCompatActivity {
- ImageView dailyReportMenuButton;
+ ImageView dailyReportMenuButton;
+
+ DrawerLayout drawerLayout;
+ NavigationView navigationView;
+
+ TextView usernameTextView;
+ TextView reportedByTextView;
+
+ EditText progressNotesEditText;
+
+ TextView urgentMedicalAttentionTextView;
+ TextView requiresHospitalisationTextView;
+ TextView notApplicableTextView;
+ TextView requiresHourlyAttentionTextView;
+
+ Button submitButton;
+
+ String patientId;
+ String patientName;
+ String selectedAlert = "Not Applicable";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_daily_report);
+
+ drawerLayout = findViewById(R.id.drawer_layout);
+ navigationView = findViewById(R.id.nav_view);
+ dailyReportMenuButton = findViewById(R.id.menuButton11);
+
+ usernameTextView = findViewById(R.id.username);
+ reportedByTextView = findViewById(R.id.save);
+ progressNotesEditText = findViewById(R.id.patientNnormal);
+
+ urgentMedicalAttentionTextView = findViewById(R.id.urgentMedicalAttentionTextView);
+ requiresHospitalisationTextView = findViewById(R.id.requiresHospitalisationTextView);
+ notApplicableTextView = findViewById(R.id.notApplicableTextView);
+ requiresHourlyAttentionTextView = findViewById(R.id.requiresHourlyAttentionTextView);
+
+ submitButton = findViewById(R.id.loginBtn);
+
+ // ADDED: Keep original menu icon colours
+ navigationView.setItemIconTintList(null);
+
+ // Open drawer when menu button is clicked
+ dailyReportMenuButton.setOnClickListener(
+ v -> drawerLayout.openDrawer(GravityCompat.START));
+
+ // Get patient data from intent
+ String patientNameExtra = getIntent().getStringExtra("patientName");
+ patientId = getIntent().getStringExtra("patientId");
+
+ // ADDED: Safe handling for null or empty patient name
+ if (patientNameExtra != null && !patientNameExtra.isEmpty()) {
+ patientName = patientNameExtra.split(" ")[0];
+ } else {
+ patientName = "Patient";
+ }
+
+ usernameTextView.setText(patientName);
+
+ // ADDED: Dummy frontend data for now
+ reportedByTextView.setText("Nurse John");
+ progressNotesEditText.setText("Patient is stable and doing well.");
+
+ // ADDED: Default selected alert
+ highlightSelectedAlert(notApplicableTextView);
+
+ // ADDED: Alert selection handling
+ urgentMedicalAttentionTextView.setOnClickListener(v -> {
+ selectedAlert = "Urgent Medical Attention";
+ highlightSelectedAlert(urgentMedicalAttentionTextView);
+ showToast(selectedAlert);
+ });
+
+ requiresHospitalisationTextView.setOnClickListener(v -> {
+ selectedAlert = "Requires Hospitalisation";
+ highlightSelectedAlert(requiresHospitalisationTextView);
+ showToast(selectedAlert);
+ });
+
+ notApplicableTextView.setOnClickListener(v -> {
+ selectedAlert = "Not Applicable";
+ highlightSelectedAlert(notApplicableTextView);
+ showToast(selectedAlert);
+ });
+
+ requiresHourlyAttentionTextView.setOnClickListener(v -> {
+ selectedAlert = "Requires Hourly Attention";
+ highlightSelectedAlert(requiresHourlyAttentionTextView);
+ showToast(selectedAlert);
+ });
+
+ // ADDED: Basic validation before submission
+ submitButton.setOnClickListener(v -> {
+ String notes = progressNotesEditText.getText().toString().trim();
+
+ if (notes.isEmpty()) {
+ Toast.makeText(this, "Please enter progress notes", Toast.LENGTH_SHORT).show();
+ } else {
+ // IMPROVED: Show submitted values for demo feedback
+ Toast.makeText(
+ this,
+ "Daily Report Submitted\nAlert: " + selectedAlert,
+ Toast.LENGTH_SHORT
+ ).show();
+ }
+ });
+
+ // ADDED: Navigation handling using actual menu ids
+ navigationView.setNavigationItemSelectedListener(item -> {
+ int id = item.getItemId();
+
+ if (id == R.id.nav_home) {
+ Toast.makeText(this, "Going to Home", Toast.LENGTH_SHORT).show();
+
+ // Uncomment when your Home activity is ready
+ // Intent intent = new Intent(DailyReportActivity.this, PatientHomeActivity.class);
+ // intent.putExtra("patientId", patientId);
+ // intent.putExtra("patientName", patientNameExtra);
+ // startActivity(intent);
+
+ } else if (id == R.id.add_task) {
+ Toast.makeText(this, "Going to Add Task", Toast.LENGTH_SHORT).show();
+
+ // Uncomment when your Add Task activity is ready
+ // Intent intent = new Intent(DailyReportActivity.this, TaskAddActivity.class);
+ // intent.putExtra("patientId", patientId);
+ // intent.putExtra("patientName", patientNameExtra);
+ // startActivity(intent);
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_daily_report);
+ } else if (id == R.id.nav_signout) {
+ // ADDED: Placeholder sign out behaviour
+ Toast.makeText(this, "Signed Out", Toast.LENGTH_SHORT).show();
- final NavigationView navigationView = findViewById(R.id.nav_view);
- dailyReportMenuButton = findViewById(R.id.menuButton11);
- final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
- navigationView.setItemIconTintList(null);
+ // Add real sign out logic here later
+ }
- dailyReportMenuButton.setOnClickListener(
- v -> {
- drawerLayout.openDrawer(GravityCompat.START);
+ drawerLayout.closeDrawer(GravityCompat.START);
+ return true;
});
+ }
- final String patientNameExtra = getIntent().getStringExtra("patientName");
- final String patientName = patientNameExtra != null ? patientNameExtra.split(" ")[0] : "";
+ // ADDED: Reusable toast method for cleaner code
+ private void showToast(String message) {
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
- final TextView usernameTextView = findViewById(R.id.username);
+ // ADDED: Simple visual feedback for selected alert
+ private void highlightSelectedAlert(TextView selectedTextView) {
+ urgentMedicalAttentionTextView.setAlpha(0.6f);
+ requiresHospitalisationTextView.setAlpha(0.6f);
+ notApplicableTextView.setAlpha(0.6f);
+ requiresHourlyAttentionTextView.setAlpha(0.6f);
- /*if (null != patientName) {
- usernameTextView.setText(patientName);
- }*/
- }
-}
+ selectedTextView.setAlpha(1.0f);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportSummaryActivity.java b/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportSummaryActivity.java
index 712605861..c464bd5fd 100644
--- a/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportSummaryActivity.java
+++ b/app/src/main/java/deakin/gopher/guardian/view/patient/dailyreport/DailyReportSummaryActivity.java
@@ -18,56 +18,74 @@
public class DailyReportSummaryActivity extends AppCompatActivity {
- private final StringBuilder statuses = new StringBuilder();
- private long dateMs;
-
- ImageView dailyReportSummaryMenuButton;
-
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_daily_report_summary);
-
- final NavigationView navigationView = findViewById(R.id.nav_view);
- dailyReportSummaryMenuButton = findViewById(R.id.menuButton101);
- final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
- navigationView.setItemIconTintList(null);
-
- dailyReportSummaryMenuButton.setOnClickListener(
- v -> {
- drawerLayout.openDrawer(GravityCompat.START);
- });
-
- final TextView currentStatusSummary = findViewById(R.id.currentStatusSummary);
- final TextView progressNotesSummary = findViewById(R.id.progressNotesSummary);
- final CalendarView patientReportSummaryCalendarView =
- findViewById(R.id.patientReportSummaryCalendarView);
-
- final Intent intent = getIntent();
- final String date = intent.getStringExtra(Util.DAILY_REPORT_DATE);
- final String notes = intent.getStringExtra(Util.DAILY_REPORT_STATUS_NOTES);
- final String[] statusList = intent.getStringArrayExtra(Util.DAILY_REPORT_STATUS_LIST);
- if (null != statusList && 0 != statusList.length) {
- for (int i = 0; i < statusList.length - 1; i++) {
- statuses.append(statusList[i]).append("\n");
- }
- statuses.append(statusList[statusList.length - 1]);
- }
+ private final StringBuilder statuses = new StringBuilder();
+ private long dateMs;
- if (android.os.Build.VERSION_CODES.N <= android.os.Build.VERSION.SDK_INT) {
- final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
+ ImageView dailyReportSummaryMenuButton;
- try {
- final Date d;
- d = formatter.parse(date);
- dateMs = d.getTime();
- } catch (final ParseException e) {
- e.printStackTrace();
- }
- }
+ TextView currentStatusSummary;
+ TextView progressNotesSummary;
+ CalendarView patientReportSummaryCalendarView;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_daily_report_summary);
+
+ final NavigationView navigationView = findViewById(R.id.nav_view);
+ final DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
+ dailyReportSummaryMenuButton = findViewById(R.id.menuButton101);
+
+ currentStatusSummary = findViewById(R.id.currentStatusSummary);
+ progressNotesSummary = findViewById(R.id.progressNotesSummary);
+ patientReportSummaryCalendarView = findViewById(R.id.patientReportSummaryCalendarView);
+
+ // ADDED: Keep original navigation icon colours
+ navigationView.setItemIconTintList(null);
+
+ // Open drawer when menu button is clicked
+ dailyReportSummaryMenuButton.setOnClickListener(
+ v -> drawerLayout.openDrawer(GravityCompat.START));
- progressNotesSummary.setText(notes);
- currentStatusSummary.setText(statuses);
- patientReportSummaryCalendarView.setDate(dateMs);
- }
-}
+ final Intent intent = getIntent();
+ final String date = intent.getStringExtra(Util.DAILY_REPORT_DATE);
+ final String notes = intent.getStringExtra(Util.DAILY_REPORT_STATUS_NOTES);
+ final String[] statusList = intent.getStringArrayExtra(Util.DAILY_REPORT_STATUS_LIST);
+
+ // ADDED: Format selected status values for summary display
+ if (statusList != null && statusList.length > 0) {
+ for (int i = 0; i < statusList.length - 1; i++) {
+ statuses.append(statusList[i]).append("\n");
+ }
+ statuses.append(statusList[statusList.length - 1]);
+ } else {
+ // ADDED: Fallback text when no statuses are passed
+ statuses.append("No status selected");
+ }
+
+ // IMPROVED: Safely parse date before updating CalendarView
+ if (date != null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+ final SimpleDateFormat formatter =
+ new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
+
+ try {
+ final Date parsedDate = formatter.parse(date);
+ if (parsedDate != null) {
+ dateMs = parsedDate.getTime();
+ patientReportSummaryCalendarView.setDate(dateMs);
+ }
+ } catch (final ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // ADDED: Fallback text for missing notes
+ if (notes != null && !notes.isEmpty()) {
+ progressNotesSummary.setText(notes);
+ } else {
+ progressNotesSummary.setText("No progress notes available");
+ }
+
+ currentStatusSummary.setText(statuses.toString());
+ }
+}
\ No newline at end of file