Files
WerkoutIOS/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift
Trey t eaa6997c18 WIP
2023-07-04 12:28:20 -05:00

247 lines
8.5 KiB
Swift

//
// AllWorkoutsView.swift
// Werkout_ios
//
// Created by Trey Tartt on 6/15/23.
//
import Foundation
import SwiftUI
struct AllWorkoutsView: View {
enum MainViews: Int, CaseIterable {
case AllWorkout = 0
case MyWorkouts
var title: String {
switch self {
case .AllWorkout:
return "All Workouts"
case .MyWorkouts:
return "Planned Workouts"
}
}
}
@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: MainViews = .AllWorkout
@State var selectedDate: Date = Date()
let pub = NotificationCenter.default.publisher(for: NSNotification.Name("CreatedNewWorkout"))
var body: some View {
ZStack {
if let workouts = workouts {
if dataStore.status == .loading {
ProgressView()
.progressViewStyle(.circular)
} else {
VStack {
Picker("", selection: $selectedSegment) {
ForEach(MainViews.allCases, id: \.self) { viewType in
Text(viewType.title)
}
}
.pickerStyle(.segmented)
.padding()
switch selectedSegment {
case .AllWorkout:
AllWorkoutsListView(workouts: workouts, selectedWorkout: { workout in
selectedWorkout = workout
})
Divider()
case .MyWorkouts:
plannedWorkout(workouts: UserStore.shared.plannedWorkouts)
}
}
}
} else {
ProgressView()
.progressViewStyle(.circular)
}
}.onAppear{
// UserStore.shared.logout()
maybeUpdateShit()
}
.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 {
dataStore.fetchAllData()
AllWorkoutFetchable().fetch(completion: { result in
needsUpdating = false
switch result {
case .success(let model):
DispatchQueue.main.async {
self.workouts = model
}
case .failure(_):
fatalError("shit broke")
}
})
}
} else {
showLoginView = true
}
}
}
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 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)
}
}
}
}
TextField("Filter", text: $searchString)
.padding(.leading)
}
}
}
struct AllWorkoutsView_Previews: PreviewProvider {
static var previews: some View {
AllWorkoutsView(workouts: PreviewData.allWorkouts())
}
}