Files
honeyDueKMP/iosApp/iosApp/Subviews/Task/TasksSection.swift
Trey t 00e303c3be Update task completion to use local kanban state update
- Add updatedTask field to TaskCompletionResponse model from API
- Modify CompleteTaskView callback to pass back the updated task
- Add updateTaskInKanban() function to AllTasksView and ResidenceDetailView
- Move completed tasks to correct kanban column without additional API call
- Remove debug print statements from ResidenceDetailView

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:50:25 -06:00

170 lines
7.3 KiB
Swift

import SwiftUI
import ComposeApp
struct TasksSection: View {
let tasksResponse: TaskColumnsResponse
let onEditTask: (TaskResponse) -> Void
let onCancelTask: (Int32) -> Void
let onUncancelTask: (Int32) -> Void
let onMarkInProgress: (Int32) -> Void
let onCompleteTask: (TaskResponse) -> Void
let onArchiveTask: (Int32) -> Void
let onUnarchiveTask: (Int32) -> Void
private var hasNoTasks: Bool {
tasksResponse.columns.allSatisfy { $0.tasks.isEmpty }
}
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Tasks")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(Color.appTextPrimary)
if hasNoTasks {
EmptyTasksView()
} else {
GeometryReader { geometry in
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 16) {
// Dynamically create columns from response
ForEach(Array(tasksResponse.columns.enumerated()), id: \.element.name) { index, column in
DynamicTaskColumnView(
column: column,
onEditTask: { task in
onEditTask(task)
},
onCancelTask: { taskId in
onCancelTask(taskId)
},
onUncancelTask: { taskId in
onUncancelTask(taskId)
},
onMarkInProgress: { taskId in
onMarkInProgress(taskId)
},
onCompleteTask: { task in
onCompleteTask(task)
},
onArchiveTask: { taskId in
onArchiveTask(taskId)
},
onUnarchiveTask: { taskId in
onUnarchiveTask(taskId)
}
)
.frame(width: geometry.size.width - 48)
}
}
.scrollTargetLayout()
.padding(.horizontal, 16)
}
.scrollTargetBehavior(.viewAligned)
}
.frame(height: 500)
}
}
}
}
#Preview {
TasksSection(
tasksResponse: TaskColumnsResponse(
columns: [
TaskColumn(
name: "upcoming_tasks",
displayName: "Upcoming",
buttonTypes: ["edit", "cancel", "uncancel", "mark_in_progress", "complete", "archive"],
icons: ["ios": "calendar", "android": "CalendarToday", "web": "calendar"],
color: "#007AFF",
tasks: [
TaskResponse(
id: 1,
residenceId: 1,
createdById: 1,
createdBy: nil,
assignedToId: nil,
assignedTo: nil,
title: "Clean Gutters",
description: "Remove all debris",
categoryId: 1,
category: TaskCategory(id: 1, name: "maintenance", description: "", icon: "", color: "", displayOrder: 0),
priorityId: 2,
priority: TaskPriority(id: 2, name: "medium", level: 2, color: "", displayOrder: 0),
statusId: 1,
status: TaskStatus(id: 1, name: "pending", description: "", color: "", displayOrder: 0),
frequencyId: 1,
frequency: TaskFrequency(id: 1, name: "monthly", days: 30, displayOrder: 0),
dueDate: "2024-12-15",
estimatedCost: 150.00,
actualCost: nil,
contractorId: nil,
isCancelled: false,
isArchived: false,
parentTaskId: nil,
completionCount: 0,
kanbanColumn: nil,
completions: [],
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-01T00:00:00Z"
)
],
count: 1
),
TaskColumn(
name: "done_tasks",
displayName: "Done",
buttonTypes: ["edit", "archive"],
icons: ["ios": "checkmark.circle", "android": "CheckCircle", "web": "check-circle"],
color: "#34C759",
tasks: [
TaskResponse(
id: 2,
residenceId: 1,
createdById: 1,
createdBy: nil,
assignedToId: nil,
assignedTo: nil,
title: "Fix Leaky Faucet",
description: "Kitchen sink fixed",
categoryId: 2,
category: TaskCategory(id: 2, name: "plumbing", description: "", icon: "", color: "", displayOrder: 0),
priorityId: 3,
priority: TaskPriority(id: 3, name: "high", level: 3, color: "", displayOrder: 0),
statusId: 3,
status: TaskStatus(id: 3, name: "completed", description: "", color: "", displayOrder: 0),
frequencyId: 6,
frequency: TaskFrequency(id: 6, name: "once", days: nil, displayOrder: 0),
dueDate: "2024-11-01",
estimatedCost: 200.00,
actualCost: nil,
contractorId: nil,
isCancelled: false,
isArchived: false,
parentTaskId: nil,
completionCount: 3,
kanbanColumn: nil,
completions: [],
createdAt: "2024-10-01T00:00:00Z",
updatedAt: "2024-11-05T00:00:00Z"
)
],
count: 1
)
],
daysThreshold: 30,
residenceId: "1"
),
onEditTask: { _ in },
onCancelTask: { _ in },
onUncancelTask: { _ in },
onMarkInProgress: { _ in },
onCompleteTask: { _ in },
onArchiveTask: { _ in },
onUnarchiveTask: { _ in }
)
.padding()
}