// // ContentView.swift // Todos // // Created by Sam Jaffe on 2/28/26. // import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var modelContext @AppStorage(UserDefaultsKeys.WeekStart) private var weekStart = Date() @Query(sort: \Project.sortOrder) private var items: [Project] @State private var selection: Project? @Binding var rotate: RotateTracking var body: some View { NavigationSplitView { List(selection: $selection) { ForEach(items, id: \.id) { item in NavigationLink(value: item) { Text(item.name) }.swipeActions(content: { Button("Delete", systemImage: "trash", role: .destructive) { deleteItem(item: item) } }) } .onMove(perform: reOrder) } .navigationSplitViewColumnWidth(min: 180, ideal: 200) .toolbar { ToolbarItem { Button(action: addItem) { Label("New Project", systemImage: "plus") } } } } detail: { if let selection = selection { ProjectPanelView(item: selection) } else { let header = items.isEmpty ? "Create a New Project" : "Select a project from the sidebar" ContentUnavailableView(header, systemImage: "doc.text.image.fill") } } .confirmationDialog("Manually run \"Save and Cleanup\"?", isPresented: $rotate.manuallyInvoked) { Button("Yes") { RotateController().saveAndRotate(items, &weekStart, &rotate) rotate.summary = nil } Button("Cancel", role: .cancel) {} } message: { if let summary = rotate.summary { Text(summary) } } .alert("Autosave", isPresented: $rotate.hasTriggeredAutosave) { Text("Cleaned up the following Tasks:\n" + (rotate.summary ?? "")) Button("OK") { rotate.hasTriggeredAutosave = false rotate.summary = nil } } message: { Text("All completed tasks/subtasks have been deleted") if let summary = rotate.summary { Text(summary) } } } private func addItem() { withAnimation { let newItem = Project(sortOrder: items.count) modelContext.insert(newItem) } } @MainActor private func reOrder(fromOffsets: IndexSet, toOffset: Int) { var tmp = items.sorted(by: Project.less) tmp.move(fromOffsets: fromOffsets, toOffset: toOffset) for (index, item) in tmp.enumerated() { item.sortOrder = index } try? self.modelContext.save() } private func deleteItem(item: Project) { if let selection = selection, selection == item { self.selection = nil } withAnimation { modelContext.delete(item) } } } #Preview { @Previewable @State var rotate = RotateTracking() ContentView(rotate: $rotate) .modelContainer(for: Project.self, inMemory: true) }