// // ProjectPanelView.swift // Todos // // Created by Sam Jaffe on 2/28/26. // import SwiftUI import SwiftData struct ProjectPanelView: View { @Environment(\.modelContext) private var modelContext @AppStorage(UserDefaultsKeys.Category) var allGroups = CodableArray() @Bindable var item: Project @State private var empty = Category() @State private var move = false var body: some View { let style = Date.FormatStyle(date: .numeric, time: .standard) HStack { TextField("", text: $item.name) .font(.title) .padding(.leading, 10) Spacer() Button(action: addItem) { Image(systemName: "plus") } .help("New Task") .padding(.trailing, 10) Toggle("Move Tasks", isOn: $move) .padding(.trailing, 10) } HStack { if let grp = $allGroups.first(where: { $0.name.wrappedValue == item.category }) { ColorPicker("", selection: grp.color).disabled(true).scaledToFit() } Picker("", selection: $item.category) { Text(empty.name).tag("") ForEach(allGroups) { group in Text(group.name) } }.help("Default category for new Tasks") Text("Created on \(item.timestamp, format: style)") } List { ForEach($item.tasks.sorted(by: Task.less)) { task in TaskView(task: task) .swipeActions { Button("Delete", systemImage: "trash", role: .destructive) { deleteItem(item: task.wrappedValue, from: item) } } ForEach(task.subtasks.sorted(by: SubTask.less)) { subtask in SubTaskView(task: subtask) .swipeActions { Button("Delete", systemImage: "trash", role: .destructive) { deleteItem(item: subtask.wrappedValue, from: task.wrappedValue) } } } .onMove(perform: { indices, index in withAnimation { task.subtasks.wrappedValue.move(fromOffsets: indices, toOffset: index) for (index, item) in task.subtasks.wrappedValue.enumerated() { item.sortOrder = index } } }).moveDisabled(!move) } .onMove(perform: { indices, index in withAnimation { item.tasks.move(fromOffsets: indices, toOffset: index) for (index, item) in item.tasks.enumerated() { item.sortOrder = index } } }).moveDisabled(!move) } } private func addItem() { withAnimation { let newTask = Task(name: "New Task", parent: item) modelContext.insert(newTask) item.tasks.append(newTask) } } private func deleteItem(item: Task, from: Project) { withAnimation { from.tasks.removeAll(where: { $0.id == item.id }) modelContext.delete(item) } } private func deleteItem(item: SubTask, from: Task) { withAnimation { from.subtasks.removeAll(where: { $0.id == item.id }) modelContext.delete(item) } } } #Preview { @Previewable @State var item = Project(timestamp: Date()) ProjectPanelView(item: item) }