feat: separate open and completed todos into collapsible sections
This commit is contained in:
@@ -13,6 +13,14 @@ class TodoList: Identifiable {
|
|||||||
items.sorted { $0.createdAt < $1.createdAt }
|
items.sorted { $0.createdAt < $1.createdAt }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var openItems: [TodoItem] {
|
||||||
|
items.filter { !$0.isCompleted }.sorted { $0.createdAt < $1.createdAt }
|
||||||
|
}
|
||||||
|
|
||||||
|
var completedItems: [TodoItem] {
|
||||||
|
items.filter { $0.isCompleted }.sorted { ($0.modifiedAt ?? $0.createdAt) > ($1.modifiedAt ?? $1.createdAt) }
|
||||||
|
}
|
||||||
|
|
||||||
init(id: UUID = UUID(), name: String, items: [TodoItem] = [], isInbox: Bool = false) {
|
init(id: UUID = UUID(), name: String, items: [TodoItem] = [], isInbox: Bool = false) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ struct ListDetailView: View {
|
|||||||
let listID: UUID
|
let listID: UUID
|
||||||
@State private var editorItem: TodoItem?
|
@State private var editorItem: TodoItem?
|
||||||
@State private var moveItem: TodoItem?
|
@State private var moveItem: TodoItem?
|
||||||
|
@State private var showCompleted = true
|
||||||
|
|
||||||
private var todoList: TodoList? {
|
private var todoList: TodoList? {
|
||||||
store.lists.first { $0.id == listID }
|
store.lists.first { $0.id == listID }
|
||||||
@@ -13,25 +14,61 @@ struct ListDetailView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
Group {
|
||||||
if let todoList {
|
if let todoList {
|
||||||
if todoList.sortedItems.isEmpty {
|
if todoList.items.isEmpty {
|
||||||
ContentUnavailableView("Keine Einträge", systemImage: "tray")
|
ContentUnavailableView("Keine Einträge", systemImage: "tray")
|
||||||
} else {
|
} else {
|
||||||
List {
|
List {
|
||||||
TodoListView(
|
Section {
|
||||||
items: todoList.sortedItems,
|
TodoListView(
|
||||||
onToggle: { item in
|
items: todoList.openItems,
|
||||||
store.toggleItemCompleted(item.id, in: listID)
|
onToggle: { item in
|
||||||
},
|
store.toggleItemCompleted(item.id, in: listID)
|
||||||
onTap: { item in
|
},
|
||||||
editorItem = item
|
onTap: { item in
|
||||||
},
|
editorItem = item
|
||||||
onDelete: { item in
|
},
|
||||||
store.deleteItem(item.id, from: listID)
|
onDelete: { item in
|
||||||
},
|
store.deleteItem(item.id, from: listID)
|
||||||
onMove: { item in
|
},
|
||||||
moveItem = item
|
onMove: { item in
|
||||||
|
moveItem = item
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !todoList.completedItems.isEmpty {
|
||||||
|
Section {
|
||||||
|
if showCompleted {
|
||||||
|
TodoListView(
|
||||||
|
items: todoList.completedItems,
|
||||||
|
onToggle: { item in
|
||||||
|
store.toggleItemCompleted(item.id, in: listID)
|
||||||
|
},
|
||||||
|
onTap: { item in
|
||||||
|
editorItem = item
|
||||||
|
},
|
||||||
|
onDelete: { item in
|
||||||
|
store.deleteItem(item.id, from: listID)
|
||||||
|
},
|
||||||
|
onMove: { item in
|
||||||
|
moveItem = item
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Button {
|
||||||
|
withAnimation {
|
||||||
|
showCompleted.toggle()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
HStack {
|
||||||
|
Text("Erledigt (\(todoList.completedItems.count))")
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: showCompleted ? "chevron.down" : "chevron.right")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user