wip
This commit is contained in:
@@ -74,10 +74,18 @@ data class TaskDetail(
|
||||
@Serializable
|
||||
data class TasksByResidenceResponse(
|
||||
@SerialName("residence_id") val residenceId: String,
|
||||
val summary: TaskSummary,
|
||||
val tasks: List<TaskDetail>,
|
||||
@SerialName("completed_tasks") val completedTasks: List<TaskDetail> = emptyList(),
|
||||
@SerialName("cancelled_tasks") val cancelledTasks: List<TaskDetail> = emptyList()
|
||||
@SerialName("days_threshold") val daysThreshold: Int,
|
||||
val summary: CategorizedTaskSummary,
|
||||
@SerialName("upcoming_tasks") val upcomingTasks: List<TaskDetail>,
|
||||
@SerialName("in_progress_tasks") val inProgressTasks: List<TaskDetail>,
|
||||
@SerialName("done_tasks") val doneTasks: List<TaskDetail>
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class CategorizedTaskSummary(
|
||||
val upcoming: Int,
|
||||
@SerialName("in_progress") val inProgress: Int,
|
||||
val done: Int
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -94,10 +94,15 @@ class TaskApi(private val client: HttpClient = ApiClient.httpClient) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getTasksByResidence(token: String, residenceId: Int): ApiResult<TasksByResidenceResponse> {
|
||||
suspend fun getTasksByResidence(
|
||||
token: String,
|
||||
residenceId: Int,
|
||||
days: Int = 30
|
||||
): ApiResult<TasksByResidenceResponse> {
|
||||
return try {
|
||||
val response = client.get("$baseUrl/tasks/by-residence/$residenceId/") {
|
||||
header("Authorization", "Token $token")
|
||||
parameter("days", days)
|
||||
}
|
||||
|
||||
if (response.status.isSuccess()) {
|
||||
|
||||
@@ -48,8 +48,8 @@ fun ResidenceDetailScreen(
|
||||
var showCompleteDialog by remember { mutableStateOf(false) }
|
||||
var selectedTask by remember { mutableStateOf<TaskDetail?>(null) }
|
||||
var showNewTaskDialog by remember { mutableStateOf(false) }
|
||||
var showCompletedTasks by remember { mutableStateOf(false) }
|
||||
var showCancelledTasks by remember { mutableStateOf(false) }
|
||||
var showInProgressTasks by remember { mutableStateOf(false) }
|
||||
var showDoneTasks by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(residenceId) {
|
||||
residenceViewModel.getResidence(residenceId) { result ->
|
||||
@@ -394,7 +394,7 @@ fun ResidenceDetailScreen(
|
||||
}
|
||||
is ApiResult.Success -> {
|
||||
val taskData = (tasksState as ApiResult.Success).data
|
||||
if (taskData.tasks.isEmpty() && taskData.completedTasks.isEmpty() && taskData.cancelledTasks.isEmpty()) {
|
||||
if (taskData.upcomingTasks.isEmpty() && taskData.inProgressTasks.isEmpty() && taskData.doneTasks.isEmpty()) {
|
||||
item {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -427,7 +427,8 @@ fun ResidenceDetailScreen(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items(taskData.tasks) { task ->
|
||||
// Upcoming tasks section
|
||||
items(taskData.upcomingTasks) { task ->
|
||||
TaskCard(
|
||||
task = task,
|
||||
onCompleteClick = {
|
||||
@@ -444,14 +445,69 @@ fun ResidenceDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
// Completed tasks section
|
||||
if (taskData.completedTasks.isNotEmpty()) {
|
||||
// In Progress tasks section
|
||||
if (taskData.inProgressTasks.isNotEmpty()) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { showCompletedTasks = !showCompletedTasks }
|
||||
.clickable { showInProgressTasks = !showInProgressTasks }
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
Icons.Default.PlayCircle,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.tertiary,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "In Progress (${taskData.inProgressTasks.size})",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
if (showInProgressTasks) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (showInProgressTasks) {
|
||||
items(taskData.inProgressTasks) { task ->
|
||||
TaskCard(
|
||||
task = task,
|
||||
onCompleteClick = {
|
||||
selectedTask = task
|
||||
showCompleteDialog = true
|
||||
},
|
||||
onEditClick = {
|
||||
onNavigateToEditTask(task)
|
||||
},
|
||||
onCancelClick = {
|
||||
residenceViewModel.cancelTask(task.id)
|
||||
},
|
||||
onUncancelClick = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done tasks section
|
||||
if (taskData.doneTasks.isNotEmpty()) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { showDoneTasks = !showDoneTasks }
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
@@ -460,77 +516,27 @@ fun ResidenceDetailScreen(
|
||||
Icon(
|
||||
Icons.Default.CheckCircle,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.tertiary,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "Completed Tasks (${taskData.completedTasks.size})",
|
||||
text = "Done (${taskData.doneTasks.size})",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
if (showCompletedTasks) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||
if (showDoneTasks) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (showCompletedTasks) {
|
||||
items(taskData.completedTasks) { task ->
|
||||
TaskCard(
|
||||
task = task,
|
||||
onCompleteClick = null,
|
||||
onEditClick = {
|
||||
onNavigateToEditTask(task)
|
||||
},
|
||||
onCancelClick = null,
|
||||
onUncancelClick = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancelled tasks section
|
||||
if (taskData.cancelledTasks.isNotEmpty()) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { showCancelledTasks = !showCancelledTasks }
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
Icons.Default.Cancel,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier.size(28.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "Cancelled Tasks (${taskData.cancelledTasks.size})",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
if (showCancelledTasks) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (showCancelledTasks) {
|
||||
items(taskData.cancelledTasks) { task ->
|
||||
if (showDoneTasks) {
|
||||
items(taskData.doneTasks) { task ->
|
||||
TaskCard(
|
||||
task = task,
|
||||
onCompleteClick = null,
|
||||
|
||||
Reference in New Issue
Block a user