wip
This commit is contained in:
@@ -76,6 +76,7 @@ data class TasksByResidenceResponse(
|
|||||||
@SerialName("residence_id") val residenceId: String,
|
@SerialName("residence_id") val residenceId: String,
|
||||||
val summary: TaskSummary,
|
val summary: TaskSummary,
|
||||||
val tasks: List<TaskDetail>,
|
val tasks: List<TaskDetail>,
|
||||||
|
@SerialName("completed_tasks") val completedTasks: List<TaskDetail> = emptyList(),
|
||||||
@SerialName("cancelled_tasks") val cancelledTasks: List<TaskDetail> = emptyList()
|
@SerialName("cancelled_tasks") val cancelledTasks: List<TaskDetail> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.mycrib.android.ui.screens
|
package com.mycrib.android.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
@@ -47,6 +48,7 @@ fun ResidenceDetailScreen(
|
|||||||
var showCompleteDialog by remember { mutableStateOf(false) }
|
var showCompleteDialog by remember { mutableStateOf(false) }
|
||||||
var selectedTask by remember { mutableStateOf<TaskDetail?>(null) }
|
var selectedTask by remember { mutableStateOf<TaskDetail?>(null) }
|
||||||
var showNewTaskDialog by remember { mutableStateOf(false) }
|
var showNewTaskDialog by remember { mutableStateOf(false) }
|
||||||
|
var showCompletedTasks by remember { mutableStateOf(false) }
|
||||||
var showCancelledTasks by remember { mutableStateOf(false) }
|
var showCancelledTasks by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
LaunchedEffect(residenceId) {
|
LaunchedEffect(residenceId) {
|
||||||
@@ -392,7 +394,7 @@ fun ResidenceDetailScreen(
|
|||||||
}
|
}
|
||||||
is ApiResult.Success -> {
|
is ApiResult.Success -> {
|
||||||
val taskData = (tasksState as ApiResult.Success).data
|
val taskData = (tasksState as ApiResult.Success).data
|
||||||
if (taskData.tasks.isEmpty() && taskData.cancelledTasks.isEmpty()) {
|
if (taskData.tasks.isEmpty() && taskData.completedTasks.isEmpty() && taskData.cancelledTasks.isEmpty()) {
|
||||||
item {
|
item {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -442,6 +444,56 @@ fun ResidenceDetailScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Completed tasks section
|
||||||
|
if (taskData.completedTasks.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { showCompletedTasks = !showCompletedTasks }
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.CheckCircle,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.tertiary,
|
||||||
|
modifier = Modifier.size(28.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Completed Tasks (${taskData.completedTasks.size})",
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = MaterialTheme.colorScheme.tertiary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Icon(
|
||||||
|
if (showCompletedTasks) 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
|
// Cancelled tasks section
|
||||||
if (taskData.cancelledTasks.isNotEmpty()) {
|
if (taskData.cancelledTasks.isNotEmpty()) {
|
||||||
item {
|
item {
|
||||||
@@ -449,6 +501,7 @@ fun ResidenceDetailScreen(
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.clickable { showCancelledTasks = !showCancelledTasks }
|
||||||
.padding(vertical = 8.dp),
|
.padding(vertical = 8.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
@@ -468,9 +521,11 @@ fun ResidenceDetailScreen(
|
|||||||
color = MaterialTheme.colorScheme.error
|
color = MaterialTheme.colorScheme.error
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TextButton(onClick = { showCancelledTasks = !showCancelledTasks }) {
|
Icon(
|
||||||
Text(if (showCancelledTasks) "Hide" else "Show")
|
if (showCancelledTasks) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||||
}
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct ResidenceDetailView: View {
|
|||||||
@State private var showEditResidence = false
|
@State private var showEditResidence = false
|
||||||
@State private var showEditTask = false
|
@State private var showEditTask = false
|
||||||
@State private var selectedTaskForEdit: TaskDetail?
|
@State private var selectedTaskForEdit: TaskDetail?
|
||||||
|
@State private var showCompletedTasks = false
|
||||||
@State private var showCancelledTasks = false
|
@State private var showCancelledTasks = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -37,6 +38,7 @@ struct ResidenceDetailView: View {
|
|||||||
if let tasksResponse = tasksResponse {
|
if let tasksResponse = tasksResponse {
|
||||||
TasksSection(
|
TasksSection(
|
||||||
tasksResponse: tasksResponse,
|
tasksResponse: tasksResponse,
|
||||||
|
showCompletedTasks: $showCompletedTasks,
|
||||||
showCancelledTasks: $showCancelledTasks,
|
showCancelledTasks: $showCancelledTasks,
|
||||||
onEditTask: { task in
|
onEditTask: { task in
|
||||||
selectedTaskForEdit = task
|
selectedTaskForEdit = task
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import ComposeApp
|
|||||||
|
|
||||||
struct TasksSection: View {
|
struct TasksSection: View {
|
||||||
let tasksResponse: TasksByResidenceResponse
|
let tasksResponse: TasksByResidenceResponse
|
||||||
|
@Binding var showCompletedTasks: Bool
|
||||||
@Binding var showCancelledTasks: Bool
|
@Binding var showCancelledTasks: Bool
|
||||||
let onEditTask: (TaskDetail) -> Void
|
let onEditTask: (TaskDetail) -> Void
|
||||||
let onCancelTask: (TaskDetail) -> Void
|
let onCancelTask: (TaskDetail) -> Void
|
||||||
@@ -24,7 +25,7 @@ struct TasksSection: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tasksResponse.tasks.isEmpty && tasksResponse.cancelledTasks.isEmpty {
|
if tasksResponse.tasks.isEmpty && tasksResponse.completedTasks.isEmpty && tasksResponse.cancelledTasks.isEmpty {
|
||||||
EmptyTasksView()
|
EmptyTasksView()
|
||||||
} else {
|
} else {
|
||||||
ForEach(tasksResponse.tasks, id: \.id) { task in
|
ForEach(tasksResponse.tasks, id: \.id) { task in
|
||||||
@@ -36,6 +37,38 @@ struct TasksSection: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !tasksResponse.completedTasks.isEmpty {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
HStack {
|
||||||
|
Label("Completed Tasks (\(tasksResponse.completedTasks.count))", systemImage: "checkmark.circle")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(.green)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Image(systemName: showCompletedTasks ? "chevron.up" : "chevron.down")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
.padding(.top, 8)
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.onTapGesture {
|
||||||
|
showCompletedTasks.toggle()
|
||||||
|
}
|
||||||
|
|
||||||
|
if showCompletedTasks {
|
||||||
|
ForEach(tasksResponse.completedTasks, id: \.id) { task in
|
||||||
|
TaskCard(
|
||||||
|
task: task,
|
||||||
|
onEdit: { onEditTask(task) },
|
||||||
|
onCancel: nil,
|
||||||
|
onUncancel: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !tasksResponse.cancelledTasks.isEmpty {
|
if !tasksResponse.cancelledTasks.isEmpty {
|
||||||
VStack(alignment: .leading, spacing: 12) {
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -45,12 +78,15 @@ struct TasksSection: View {
|
|||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button(showCancelledTasks ? "Hide" : "Show") {
|
Image(systemName: showCancelledTasks ? "chevron.up" : "chevron.down")
|
||||||
showCancelledTasks.toggle()
|
.foregroundColor(.secondary)
|
||||||
}
|
.font(.caption)
|
||||||
.font(.subheadline)
|
|
||||||
}
|
}
|
||||||
.padding(.top, 8)
|
.padding(.top, 8)
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.onTapGesture {
|
||||||
|
showCancelledTasks.toggle()
|
||||||
|
}
|
||||||
|
|
||||||
if showCancelledTasks {
|
if showCancelledTasks {
|
||||||
ForEach(tasksResponse.cancelledTasks, id: \.id) { task in
|
ForEach(tasksResponse.cancelledTasks, id: \.id) { task in
|
||||||
@@ -101,8 +137,30 @@ struct TasksSection: View {
|
|||||||
completions: []
|
completions: []
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
completedTasks: [
|
||||||
|
TaskDetail(
|
||||||
|
id: 2,
|
||||||
|
residence: 1,
|
||||||
|
title: "Fix Leaky Faucet",
|
||||||
|
description: "Kitchen sink fixed",
|
||||||
|
category: TaskCategory(id: 2, name: "plumbing", description: "Plumbing tasks"),
|
||||||
|
priority: TaskPriority(id: 3, name: "high", displayName: "High", description: "High priority"),
|
||||||
|
frequency: TaskFrequency(id: 6, name: "once", displayName: "One Time"),
|
||||||
|
status: TaskStatus(id: 3, name: "completed", displayName: "Completed", description: "Task completed"),
|
||||||
|
dueDate: "2024-11-01",
|
||||||
|
estimatedCost: "200.00",
|
||||||
|
actualCost: "185.00",
|
||||||
|
notes: nil,
|
||||||
|
createdAt: "2024-10-01T00:00:00Z",
|
||||||
|
updatedAt: "2024-11-05T00:00:00Z",
|
||||||
|
nextScheduledDate: nil,
|
||||||
|
showCompletedButton: false,
|
||||||
|
completions: []
|
||||||
|
)
|
||||||
|
],
|
||||||
cancelledTasks: []
|
cancelledTasks: []
|
||||||
),
|
),
|
||||||
|
showCompletedTasks: .constant(true),
|
||||||
showCancelledTasks: .constant(true),
|
showCancelledTasks: .constant(true),
|
||||||
onEditTask: { _ in },
|
onEditTask: { _ in },
|
||||||
onCancelTask: { _ in },
|
onCancelTask: { _ in },
|
||||||
|
|||||||
Reference in New Issue
Block a user