239 lines
9.0 KiB
Swift
239 lines
9.0 KiB
Swift
//
|
|
// CreateWorkout.swift
|
|
// Werkout_ios
|
|
//
|
|
// Created by Trey Tartt on 6/15/23.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
import Combine
|
|
|
|
struct AddExerciseView: View {
|
|
enum CreateWorkoutItemPickerViewType {
|
|
case muscles
|
|
case equipment
|
|
}
|
|
|
|
@State var selectedMuscles = [Muscle]()
|
|
@State var selectedEquipment = [Equipment]()
|
|
@State var filteredExercises = [ExerciseExercise]()
|
|
|
|
@StateObject var bridgeModule = BridgeModule.shared
|
|
@Environment(\.dismiss) var dismiss
|
|
var selectedWorkout: ((ExerciseExercise) -> Void)
|
|
@State var createWorkoutItemPickerViewModel: CreateWorkoutItemPickerViewModel?
|
|
@State var createWorkoutItemPickerViewType: CreateWorkoutItemPickerViewType?
|
|
@State var searchString: String = ""
|
|
|
|
var body: some View {
|
|
VStack {
|
|
exerciseView()
|
|
.padding(.top)
|
|
|
|
TextField("Filter", text: $searchString)
|
|
.padding()
|
|
|
|
HStack {
|
|
muscleView()
|
|
.frame(maxWidth: .infinity)
|
|
|
|
Divider()
|
|
|
|
equipmentView()
|
|
.frame(maxWidth: .infinity)
|
|
}
|
|
.padding(.top)
|
|
.frame(height: 44)
|
|
}
|
|
.onAppear{
|
|
if #function.hasPrefix("__preview") {
|
|
DataStore.shared.setupFakeData()
|
|
}
|
|
guard let exercises = DataStore.shared.allExercise,
|
|
let muscles = DataStore.shared.allMuscles,
|
|
let equipment = DataStore.shared.allEquipment else {
|
|
return
|
|
}
|
|
selectedMuscles = muscles
|
|
selectedEquipment = equipment
|
|
filteredExercises = exercises
|
|
}
|
|
.sheet(item: $createWorkoutItemPickerViewModel) { item in
|
|
CreateWorkoutItemPickerView(viewModel: item, completed: { selectedids in
|
|
if let viewType = createWorkoutItemPickerViewType {
|
|
switch viewType {
|
|
case .muscles:
|
|
if let muscles = DataStore.shared.allMuscles {
|
|
selectedMuscles.removeAll()
|
|
for id in selectedids {
|
|
if let muscle = muscles.first(where: {
|
|
$0.id == id
|
|
}) {
|
|
selectedMuscles.append(muscle)
|
|
}
|
|
}
|
|
}
|
|
case .equipment:
|
|
if let equipment = DataStore.shared.allEquipment {
|
|
selectedEquipment.removeAll()
|
|
for id in selectedids {
|
|
if let equipment = equipment.first(where: {
|
|
$0.id == id
|
|
}) {
|
|
selectedEquipment.append(equipment)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
filterExercises()
|
|
})
|
|
}
|
|
.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
|
|
}
|
|
}
|
|
|
|
return hasCorrectMuscles && hasCorrectEquipment
|
|
})
|
|
}
|
|
|
|
func muscleView() -> some View {
|
|
VStack {
|
|
if let _ = DataStore.shared.allMuscles {
|
|
Text("Select Muscles")
|
|
.foregroundColor(.cyan)
|
|
Text("\(selectedMuscles.count) Selected")
|
|
}
|
|
}
|
|
.onTapGesture {
|
|
if let muscles = DataStore.shared.allMuscles {
|
|
var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]()
|
|
muscles.forEach({
|
|
let model = CreateWorkoutItemPickerModel(id: $0.id, name: $0.name.lowercased())
|
|
createWorkoutItemPickerModels.append(model)
|
|
})
|
|
createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: {
|
|
$0.name < $1.name
|
|
})
|
|
let selectedIds = selectedMuscles.map { $0.id }
|
|
createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds)
|
|
createWorkoutItemPickerViewType = .muscles
|
|
}
|
|
}
|
|
}
|
|
|
|
func equipmentView() -> some View {
|
|
VStack {
|
|
if let _ = DataStore.shared.allEquipment {
|
|
Text("Select Equipment")
|
|
.foregroundColor(.cyan)
|
|
Text("\(selectedEquipment.count) Selected")
|
|
}
|
|
}
|
|
.onTapGesture {
|
|
if let equipment = DataStore.shared.allEquipment {
|
|
var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]()
|
|
equipment.forEach({
|
|
let model = CreateWorkoutItemPickerModel(id: $0.id,
|
|
name: $0.name?.lowercased() ?? "-")
|
|
createWorkoutItemPickerModels.append(model)
|
|
})
|
|
createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: {
|
|
$0.name < $1.name
|
|
})
|
|
let selectedIds = selectedEquipment.map { $0.id }
|
|
createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds)
|
|
createWorkoutItemPickerViewType = .equipment
|
|
}
|
|
}
|
|
}
|
|
|
|
func exerciseView() -> some View {
|
|
List() {
|
|
ForEach(filteredExercises.indices, id: \.self) { i in
|
|
let obj = filteredExercises[i]
|
|
if searchString.isEmpty || obj.name.lowercased().contains(searchString.lowercased()) {
|
|
HStack {
|
|
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()
|
|
}
|
|
Button(action: {
|
|
}) {
|
|
Image(systemName: "video.fill")
|
|
}
|
|
.frame(width: 22, height: 22)
|
|
.background(.clear)
|
|
.foregroundColor(.blue)
|
|
.cornerRadius(10)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AddExerciseView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
AddExerciseView(selectedWorkout: { _ in })
|
|
}
|
|
}
|