// // ExerciseLibraryView.swift // WorkoutsPlus // // Created by Felix Förtsch on 10.08.24. // import SwiftUI import SwiftData struct ExerciseLibrary: View { @Environment(\.modelContext) private var modelContext @Query(sort: \Exercise.name) private var exercises: [Exercise] @State private var newExercise: Exercise? var body: some View { NavigationSplitView { Group { if !exercises.isEmpty { List { ForEach(exercises) { exercise in NavigationLink { ExerciseDetail(exercise: exercise) } label: { Text(exercise.name) } } .onDelete(perform: deleteExercise) } } else { ContentUnavailableView { Label("No Exercises", systemImage: Exercise.systemImage) } } } .navigationBarTitle("Exercises") .toolbar { ToolbarItem(placement: .topBarLeading) { EditButton() } ToolbarItem { Button(action: addExercise) { Label("Add Exercise", systemImage: "plus") } } } .sheet(item: $newExercise) { exercise in NavigationStack { AddExercise(exercise: exercise) } // TODO: It's possible to add a boolean here ("Terms accepted y/n"). Maybe add this for empty string .interactiveDismissDisabled() } } detail: { // TODO: What does this Detail do? Text("Select a workout") .navigationTitle("Movie") } } private func addExercise() { withAnimation { let item = Exercise("") modelContext.insert(item) newExercise = item } } private func saveExercise(exercise: Exercise) { if !exercise.name.isEmpty { modelContext.insert(exercise) try? modelContext.save() } } private func deleteExercise(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(exercises[index]) } try? modelContext.save() } } } #Preview("With Sample Data") { ExerciseLibrary() .modelContainer(SampleData.shared.modelContainer) } #Preview("Empty Database") { ExerciseLibrary() .modelContainer(for: Exercise.self, inMemory: true) }