// // CreateWorkout.swift // Werkout_ios // // Created by Trey Tartt on 6/15/23. // import Foundation import SwiftUI struct AddExerciseView: View { @State var exercises: [ExerciseExercise]? @State var equipment: [Equipment]? @State var muscles: [Muscle]? @State var selectedMuscles = [Muscle]() @State var selectedEquipment = [Equipment]() @State var filteredExercises = [ExerciseExercise]() @EnvironmentObject var bridgeModule: BridgeModule @Environment(\.dismiss) var dismiss var selectedWorkout: ((ExerciseExercise) -> Void) var body: some View { VStack { if let muscles = muscles { 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) } if let equipment = equipment { 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) } List() { ForEach(filteredExercises.indices, id: \.self) { i in let obj = filteredExercises[i] VStack { Text(obj.name) .frame(maxWidth: .infinity, alignment: .leading) 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) } .onTapGesture { selectedWorkout(obj) dismiss() } } } } .onAppear{ parseMuscle() parseEquipment() parseExercises() } } func filterExercises() { if selectedMuscles.count == 0 { filteredExercises = [ExerciseExercise]() return } if selectedEquipment.count == 0 { filteredExercises = [ExerciseExercise]() return } guard let exercises = exercises, let muscles = muscles, let equipment = equipment 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 } } return hasCorrectMuscles && hasCorrectEquipment }) } func parseExercises() { if let filepath = Bundle.main.path(forResource: "Exercises", ofType: "json") { do { let data = try Data(NSData(contentsOfFile: filepath)) let workout = try JSONDecoder().decode([ExerciseExercise].self, from: data) self.filteredExercises.append(contentsOf: workout) self.exercises = workout } catch { print(error) fatalError() } } else { fatalError() } } func parseEquipment() { if let filepath = Bundle.main.path(forResource: "Equipment", ofType: "json") { do { let data = try Data(NSData(contentsOfFile: filepath)) let workout = try JSONDecoder().decode([Equipment].self, from: data) self.equipment = workout self.selectedEquipment.append(contentsOf: workout) } catch { print(error) fatalError() } } else { fatalError() } } func parseMuscle() { if let filepath = Bundle.main.path(forResource: "AllMuscles", ofType: "json") { do { let data = try Data(NSData(contentsOfFile: filepath)) let workout = try JSONDecoder().decode([Muscle].self, from: data) self.muscles = workout self.selectedMuscles.append(contentsOf: workout) } catch { print(error) fatalError() } } else { fatalError() } } }