Files
workoutsplus/WorkoutsPlus/Exercise/ExerciseLibrary.swift

108 lines
2.8 KiB
Swift

//
// 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
})
.focused($isInputFieldFocused)
}
Button(action: {
addExerciseTemplate()
}) {
HStack {
Image(systemName: "plus.circle.fill")
.foregroundStyle(.green)
Text("Add Exercise")
}
}
}
.searchable(text: $searchText)
}
.navigationBarTitle("Exercise Library")
.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)
}