// // CreateWorkout.swift // Werkout_ios // // Created by Trey Tartt on 6/15/23. // import Foundation import SwiftUI import Combine struct AddExerciseView: View { @State var selectedMuscles = [Muscle]() @State var selectedEquipment = [Equipment]() @State var filteredExercises = [ExerciseExercise]() @State var searchString: String = "" @StateObject var bridgeModule = BridgeModule.shared @Environment(\.dismiss) var dismiss var selectedWorkout: ((ExerciseExercise) -> Void) var body: some View { VStack { if let muscles = DataStore.shared.allMuscles { Button("toggle all", action: { if self.selectedMuscles.count > 0 { self.selectedMuscles.removeAll() } else { self.selectedMuscles.append(contentsOf: muscles) } filterExercises() }) ScrollView(.horizontal) { HStack(spacing: 10) { ForEach(muscles, id:\.id) { muscle in ZStack { RoundedRectangle(cornerRadius: 8) .stroke(selectedMuscles.contains(where: { $0.id == muscle.id }) ? .green : .gray, lineWidth: 3) .frame(maxWidth: .infinity, maxHeight: .infinity) Text(muscle.name) .lineLimit(2) .multilineTextAlignment(.center) .frame(maxWidth: .infinity, maxHeight: .infinity) } .contentShape(Rectangle()) .onTapGesture { if selectedMuscles.contains(where: { $0.id == muscle.id }) { self.selectedMuscles.removeAll(where: { $0.id == muscle.id }) } else { self.selectedMuscles.append(muscle) } filterExercises() } .frame(width: 150, height: 70) } }.padding() }.frame(height: 100) } Divider() if let equipment = DataStore.shared.allEquipment { Button("toggle all", action: { if self.selectedEquipment.count > 0 { self.selectedEquipment.removeAll() } else { self.selectedEquipment.append(contentsOf: equipment) } filterExercises() }) ScrollView(.horizontal) { HStack(spacing: 10) { ForEach(equipment, id:\.id) { aequipment in ZStack { RoundedRectangle(cornerRadius: 8) .stroke(selectedEquipment.contains(where: { $0.id == aequipment.id }) ? .green : .gray, lineWidth: 3) .frame(maxWidth: .infinity, maxHeight: .infinity) Text(aequipment.name ?? "--") .frame(maxWidth: .infinity, maxHeight: .infinity) .lineLimit(2) .multilineTextAlignment(.center) } .contentShape(Rectangle()) .onTapGesture { if selectedEquipment.contains(where: { $0.id == aequipment.id }) { self.selectedEquipment.removeAll(where: { $0.id == aequipment.id }) } else { self.selectedEquipment.append(aequipment) } filterExercises() } .frame(width: 150, height: 70) } }.padding() }.frame(height: 100) } Divider() TextField("Filter", text: $searchString) .onReceive(Just(searchString)) { location in filterExercises() } .padding() Divider() List() { ForEach(filteredExercises.indices, id: \.self) { i in let obj = filteredExercises[i] VStack { Text(obj.name) .frame(maxWidth: .infinity, alignment: .leading) if obj.side.count > 0 { Text(obj.side) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } Text(obj.equipmentRequired) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) Text(obj.muscleGroups) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } .contentShape(Rectangle()) .onTapGesture { selectedWorkout(obj) dismiss() } } } } .onAppear{ guard let exercises = DataStore.shared.allExercise, let muscles = DataStore.shared.allMuscles, let equipment = DataStore.shared.allEquipment else { return } selectedMuscles = muscles selectedEquipment = equipment filteredExercises = exercises } .background(Color(uiColor: .tertiarySystemBackground)) } func filterExercises() { if selectedMuscles.count == 0 { filteredExercises = [ExerciseExercise]() return } if selectedEquipment.count == 0 { filteredExercises = [ExerciseExercise]() return } guard let exercises = DataStore.shared.allExercise, let muscles = DataStore.shared.allMuscles, let equipment = DataStore.shared.allEquipment else { filteredExercises = [ExerciseExercise]() return } filteredExercises = exercises.filter({ exercise in var hasCorrectMuscles = false if selectedMuscles.count == muscles.count { hasCorrectMuscles = true } else { let exerciseMuscleIds = exercise.muscles.map({ $0.muscle }) let selctedMuscleIds = selectedMuscles.map({ $0.id }) if exerciseMuscleIds.contains(selctedMuscleIds) { hasCorrectMuscles = true } } var hasCorrectEquipment = false if selectedEquipment.count == equipment.count { hasCorrectEquipment = true } else { let exerciseEquipmentIds = exercise.equipment.map({ $0.equipment }) let selctedEquipmentIds = selectedEquipment.map({ $0.id }) if exerciseEquipmentIds.contains(selctedEquipmentIds) { hasCorrectEquipment = true } } if !searchString.isEmpty { return exercise.name.contains(searchString) && hasCorrectMuscles && hasCorrectEquipment } else { return hasCorrectMuscles && hasCorrectEquipment } }) } func setupFake() { DataStore.shared.setupFakeData() } } struct AddExerciseView_Previews: PreviewProvider { static var previews: some View { AddExerciseView(selectedWorkout: { _ in }) } }