// // 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: \ExerciseTemplate.name) private var exerciseTemplates: [ExerciseTemplate] @State private var newExerciseTemplate: ExerciseTemplate = ExerciseTemplate("") @State private var newExerciseName: String = "" @State private var isAddingExerciseTemplate: Bool = false @FocusState private var isInputFieldFocused: Bool @State private var searchText: String = "" var filteredItems: [ExerciseTemplate] { if searchText.isEmpty { return exerciseTemplates } else { return exerciseTemplates.filter { $0.name.localizedCaseInsensitiveContains(searchText) } } } // TODO: Add search bar to the top var body: some View { NavigationView { Group { List { ForEach(filteredItems) { exerciseTemplate in NavigationLink { ExerciseDetail(exerciseTemplate: exerciseTemplate) } label: { Text(exerciseTemplate.name) } } .onDelete(perform: deleteExercise) if isAddingExerciseTemplate { TextField("New Exercise", text: $newExerciseName, onCommit: { newExerciseTemplate.name = newExerciseName saveExercise(exerciseTemplate: newExerciseTemplate) isAddingExerciseTemplate = false }) .textInputAutocapitalization(.words) .focused($isInputFieldFocused) } AddItemButton(label: "Exercise", action: addExerciseTemplate) } .searchable(text: $searchText) } .navigationBarTitle("Exercises") .toolbar { ToolbarItem { EditButton() } } } } private func addExerciseTemplate() { withAnimation { newExerciseTemplate = ExerciseTemplate("") newExerciseName = "" isAddingExerciseTemplate = true isInputFieldFocused = true } } private func saveExercise(exerciseTemplate: ExerciseTemplate) { if !exerciseTemplate.name.isEmpty { modelContext.insert(exerciseTemplate) try? modelContext.save() } } private func deleteExercise(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(exerciseTemplates[index]) } try? modelContext.save() } } } #Preview("With Sample Data") { ExerciseLibrary() .modelContainer(SampleData.shared.modelContainer) } #Preview("Empty Database") { ExerciseLibrary() .modelContainer(for: Exercise.self, inMemory: true) }