Created task item and its adapter

This commit is contained in:
Marta Borgia Leiva 2026-02-12 11:42:33 +01:00
parent e9e2ac3d2a
commit 74da0d98bc
2 changed files with 219 additions and 0 deletions

View file

@ -0,0 +1,140 @@
package com.campusaula.edbole.kanban_clone_android.ui.adapters
import android.content.Intent
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.Button
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.campusaula.edbole.kanban_clone_android.R
import com.campusaula.edbole.kanban_clone_android.kanban.Task
import com.campusaula.edbole.kanban_clone_android.kanban.TaskStatus
import com.campusaula.edbole.kanban_clone_android.kanban.TaskUpdate
import com.campusaula.edbole.kanban_clone_android.network.ApiService
import com.campusaula.edbole.kanban_clone_android.ui.TaskEditActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class ProjectTaskAdapter(
private var tasks: List<Task>,
private val apiService: ApiService,
private val projectId: Int,
private val onTaskUpdated: () -> Unit = {},
private val onEditTask: () -> Unit = {}
) : RecyclerView.Adapter<ProjectTaskAdapter.ViewHolder>() {
private val adapterScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_task, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(tasks[position])
}
override fun getItemCount(): Int = tasks.size
fun submitList(newList: List<Task>) {
tasks = newList
notifyDataSetChanged()
}
// Cancelar el CoroutineScope cuando el adaptador ya no sea necesario
fun onDestroy() {
adapterScope.cancel()
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val taskTitleText: TextView = itemView.findViewById(R.id.taskTitleText)
private val taskDescriptionText: TextView = itemView.findViewById(R.id.taskDescriptionText)
private val editTaskButton: Button = itemView.findViewById(R.id.editTaskButton)
private val taskStatusPicker: Spinner = itemView.findViewById(R.id.taskStatusDropdown)
fun bind(task: Task) {
taskTitleText.text = task.title
taskDescriptionText.text = task.description
editTaskButton.setOnClickListener {
val intent = Intent(itemView.context, TaskEditActivity::class.java)
intent.putExtra("project_id", projectId)
intent.putExtra("task_id", task.id)
intent.putExtra("task_title", task.title)
intent.putExtra("task_description", task.description)
intent.putExtra("task_status", task.status.name)
itemView.context.startActivity(intent)
onEditTask() // Cerrar la actividad
}
taskStatusPicker.setSelection(TaskStatus.entries.indexOf(task.status))
taskStatusPicker.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
val selectedStatus: TaskStatus = TaskStatus.entries[position]
task.status = selectedStatus
adapterScope.launch {
try {
Log.d("ProjectTaskAdapter", "Sending PUT request for task: ${task.id}")
Log.d("ProjectTaskAdapter", "Project ID: $projectId")
Log.d("ProjectTaskAdapter", "TaskUpdate data: ${TaskUpdate(null, null, task.status)}")
val response = apiService.updateProjectTask(
projectId,
task.id,
TaskUpdate(null, null, task.status)
)
if (response.isSuccessful) {
Log.d("ProjectTaskAdapter", "Task updated successfully: ${task.id}")
withContext(Dispatchers.Main) {
onTaskUpdated()
notifyDataSetChanged()
}
} else {
val errorBody = response.errorBody()?.string()
Log.e("ProjectTaskAdapter", "Error response: $errorBody")
withContext(Dispatchers.Main) {
Toast.makeText(
itemView.context,
"Error updating task: ${response.code()} - $errorBody",
Toast.LENGTH_SHORT
).show()
}
}
} catch (e: Exception) {
Log.e("ProjectTaskAdapter", "Exception updating task: ${e.message}")
withContext(Dispatchers.Main) {
Toast.makeText(
itemView.context,
"Failed to update task: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// No action needed
}
}
}
}
}

View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|top"
android:layout_margin="4dp"
android:id="@+id/linearLayout2">
<LinearLayout
android:orientation="vertical"
android:layout_width="331dp"
android:layout_height="50dp"
android:id="@+id/linearLayout3"
tools:layout_editor_absoluteY="4dp"
tools:layout_editor_absoluteX="4dp">
<TextView
android:id="@+id/taskTitleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Task Title"
android:textSize="20dp"
android:textStyle="bold"
android:paddingBottom="4dp" />
<TextView
android:id="@+id/taskDescriptionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="Task Description"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/taskStatusLinearLayout"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="4dp">
<TextView
android:text="STATUS:"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/taskStatusLabel"
android:textStyle="bold"
android:textAlignment="textStart"
android:gravity="start|center_vertical" />
<Spinner
android:id="@+id/taskStatusDropdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/task_status_options"
android:layout_marginStart="16dp"
android:spinnerMode="dropdown"
android:dropDownWidth="wrap_content" />
</LinearLayout>
<Button
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="@+id/editTaskButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.5"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:icon="@android:drawable/ic_menu_edit"
style="@style/Widget.Material3.Button.IconButton"
app:iconTint="#0C0808" />
</androidx.constraintlayout.widget.ConstraintLayout>