87 lines
2.5 KiB
Swift
87 lines
2.5 KiB
Swift
import SwiftUI
|
|
|
|
struct BoardView: View {
|
|
@EnvironmentObject private var store: TaskStore
|
|
@State private var newTaskTitle = ""
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 20) {
|
|
Text("My board")
|
|
.font(.largeTitle.bold())
|
|
|
|
HStack(spacing: 12) {
|
|
TextField("Add a task", text: $newTaskTitle)
|
|
.textFieldStyle(.roundedBorder)
|
|
.onSubmit(addTask)
|
|
Button("Add", action: addTask)
|
|
.keyboardShortcut(.defaultAction)
|
|
}
|
|
|
|
HStack(alignment: .top, spacing: 16) {
|
|
ForEach(TaskList.allCases) { list in
|
|
TaskColumn(list: list, tasks: tasks(in: list))
|
|
}
|
|
}
|
|
}
|
|
.padding(24)
|
|
.frame(minWidth: 780, minHeight: 460)
|
|
}
|
|
|
|
private func tasks(in list: TaskList) -> [TaskItem] {
|
|
store.tasks.filter { $0.list == list }
|
|
}
|
|
|
|
private func addTask() {
|
|
store.add(title: newTaskTitle)
|
|
newTaskTitle = ""
|
|
}
|
|
}
|
|
|
|
private struct TaskColumn: View {
|
|
@EnvironmentObject private var store: TaskStore
|
|
let list: TaskList
|
|
let tasks: [TaskItem]
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 10) {
|
|
Text(list.title)
|
|
.font(.headline)
|
|
ScrollView {
|
|
LazyVStack(spacing: 8) {
|
|
ForEach(tasks) { task in
|
|
TaskCard(task: task)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.padding(12)
|
|
.frame(maxWidth: .infinity, minHeight: 320, alignment: .topLeading)
|
|
.background(.quaternary, in: RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
}
|
|
|
|
private struct TaskCard: View {
|
|
@EnvironmentObject private var store: TaskStore
|
|
let task: TaskItem
|
|
|
|
var body: some View {
|
|
HStack(alignment: .top, spacing: 8) {
|
|
Text(task.title)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
Menu {
|
|
ForEach(TaskList.allCases.filter { $0 != task.list }) { list in
|
|
Button("Move to \(list.title)") { store.move(task, to: list) }
|
|
}
|
|
Divider()
|
|
Button("Delete", role: .destructive) { store.delete(task) }
|
|
} label: {
|
|
Image(systemName: "ellipsis")
|
|
}
|
|
.menuStyle(.borderlessButton)
|
|
.fixedSize()
|
|
}
|
|
.padding(10)
|
|
.background(.background, in: RoundedRectangle(cornerRadius: 8))
|
|
}
|
|
}
|