// // AllWorkoutsView.swift // Werkout_ios // // Created by Trey Tartt on 6/15/23. // import Foundation import SwiftUI enum MainViewTypes: Int, CaseIterable { case AllWorkout = 0 case MyWorkouts var title: String { switch self { case .AllWorkout: return "All Workouts" case .MyWorkouts: return "Planned Workouts" } } } struct AllWorkoutsView: View { @State var isUpdating = false @State var workouts: [Workout]? var bridgeModule = BridgeModule.shared @State public var needsUpdating: Bool = true @ObservedObject var dataStore = DataStore.shared @State private var showWorkoutDetail = false @State private var selectedWorkout: Workout? { didSet { bridgeModule.currentWorkout = selectedWorkout } } @State private var selectedPlannedWorkout: Workout? { didSet { bridgeModule.currentWorkout = selectedPlannedWorkout } } @State private var showLoginView = false @State private var selectedSegment: MainViewTypes = .AllWorkout @State var selectedDate: Date = Date() let pub = NotificationCenter.default.publisher(for: NSNotification.Name("CreatedNewWorkout")) var body: some View { ZStack { if let workouts = workouts { VStack { AllWorkoutPickerView(mainViews: MainViewTypes.allCases, selectedSegment: $selectedSegment, showCurrentWorkout: { selectedWorkout = bridgeModule.currentWorkout }) switch selectedSegment { case .AllWorkout: if isUpdating { ProgressView() .progressViewStyle(.circular) } AllWorkoutsListView(workouts: workouts, selectedWorkout: { workout in selectedWorkout = workout }, refresh: { self.needsUpdating = true maybeUpdateShit() }) Divider() case .MyWorkouts: plannedWorkout(workouts: UserStore.shared.plannedWorkouts) } } } else { ProgressView() .progressViewStyle(.circular) } }.onAppear{ // UserStore.shared.logout() maybeUpdateShit() } .background(Color(uiColor: .systemGroupedBackground)) .sheet(item: $selectedWorkout) { item in let viewModel = WorkoutDetailViewModel(workout: item) WorkoutDetailView(viewModel: viewModel) } .sheet(item: $selectedPlannedWorkout) { item in let viewModel = WorkoutDetailViewModel(workout: item) WorkoutDetailView(viewModel: viewModel, showAddToCalendar: false) } .sheet(isPresented: $showLoginView) { LoginView(completion: { self.needsUpdating = true maybeUpdateShit() }) } .onReceive(pub) { (output) in self.needsUpdating = true maybeUpdateShit() } } func plannedWorkout(workouts: [PlannedWorkout]) -> some View { List { ForEach(workouts, id:\.workout.name) { plannedWorkout in HStack { VStack(alignment: .leading) { Text(plannedWorkout.onDate.plannedDate?.weekDay ?? "-") .font(.title) Text(plannedWorkout.onDate.plannedDate?.monthString ?? "-") .font(.title) Text(plannedWorkout.onDate.plannedDate?.dateString ?? "-") .font(.title) } Divider() VStack { Text(plannedWorkout.workout.name) .font(.title) .frame(maxWidth: .infinity, alignment: .leading) Text(plannedWorkout.workout.description ?? "") .font(.body) .frame(maxWidth: .infinity, alignment: .leading) Text(plannedWorkout.onDate) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } .contentShape(Rectangle()) .onTapGesture { selectedPlannedWorkout = plannedWorkout.workout } } } } } func maybeUpdateShit() { if UserStore.shared.token != nil{ if UserStore.shared.plannedWorkouts.isEmpty { UserStore.shared.fetchPlannedWorkouts() } if needsUpdating { self.isUpdating = true dataStore.fetchAllData() AllWorkoutFetchable().fetch(completion: { result in needsUpdating = false switch result { case .success(let model): DispatchQueue.main.async { self.workouts = model self.isUpdating = false } case .failure(_): DispatchQueue.main.async { self.isUpdating = false } } }) } } else { showLoginView = true } } } struct AllWorkoutPickerView: View { var mainViews: [MainViewTypes] @Binding var selectedSegment: MainViewTypes @StateObject var bridgeModule = BridgeModule.shared var showCurrentWorkout: (() -> Void) var body: some View { HStack { Picker("", selection: $selectedSegment) { ForEach(mainViews, id: \.self) { viewType in Text(viewType.title) } } .pickerStyle(.segmented) .padding([.top, .leading, .trailing]) if bridgeModule.isInWorkout { Button(action: { showCurrentWorkout() }, label: { Image(systemName: "figure.strengthtraining.traditional") .padding(.trailing) }) .tint(.blue) } } } } struct AllWorkoutsListView: View { @State var searchString: String = "" let workouts: [Workout] let selectedWorkout: ((Workout) -> Void) var filteredWorkouts: [Workout] { if !searchString.isEmpty, searchString.count > 0 { return workouts.filter({ if $0.name.lowercased().contains(searchString.lowercased()) { return true } if let equipment = $0.equipment?.joined(separator: "").lowercased(), equipment.contains(searchString.lowercased()) { return true } if let muscles = $0.muscles?.joined(separator: "").lowercased(), muscles.contains(searchString.lowercased()) { return true } return false }) } else { return workouts } } var refresh: (() -> Void) var body: some View { VStack { List { ForEach(filteredWorkouts, id:\.name) { workout in Section { VStack { Text(workout.name) .font(.title2) .frame(maxWidth: .infinity, alignment: .leading) Text(workout.description ?? "") .frame(maxWidth: .infinity, alignment: .leading) if let muscles = workout.muscles, muscles.joined(separator: ", ").count > 0{ Divider() Text(muscles.joined(separator: ", ")) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } if let equipment = workout.equipment, equipment.joined(separator: ", ").count > 0 { Divider() Text(equipment.joined(separator: ", ")) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } } .contentShape(Rectangle()) .onTapGesture { selectedWorkout(workout) } } } } .refreshable { refresh() } TextField("Filter" ,text: $searchString) .padding() .textFieldStyle(OvalTextFieldStyle()) // TextField("Filter", text: $searchString) // .padding() // .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color(uiColor: .darkGray), style: StrokeStyle(lineWidth: 1.0))) // .padding() // .background(Color(uiColor: .systemGroupedBackground)) } } } struct AllWorkoutsView_Previews: PreviewProvider { static var previews: some View { AllWorkoutsView(workouts: PreviewData.allWorkouts()) } }