feat: separate open and completed todos into collapsible sections

This commit is contained in:
2026-02-12 22:42:13 +01:00
parent 29719b7499
commit 3d9dd8cd8f
2 changed files with 60 additions and 15 deletions

View File

@@ -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

View File

@@ -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")
}
}
} }
) }
} }
} }
} }