From fbc1ada8c9dce2820d577f22eb4bc8a1f1559504 Mon Sep 17 00:00:00 2001 From: Trey t Date: Sun, 2 Jul 2023 16:37:45 -0500 Subject: [PATCH] WIP --- Werkout_ios.xcodeproj/project.pbxproj | 12 ++ .../xcschemes/Werkout_ios.xcscheme | 77 ++++++++++++ .../Werkout_watch Watch App.xcscheme | 91 ++++++++++++++ .../xcschemes/xcschememanagement.plist | 13 ++ Werkout_ios/APIModels/PlannedWorkout.swift | 29 +++++ Werkout_ios/DataStore.swift | 7 +- Werkout_ios/Extensions.swift | 35 ++++++ Werkout_ios/JSON/PlannedWorkouts.json | 16 +++ Werkout_ios/Network/Fetchables.swift | 17 +++ Werkout_ios/Network/Network.swift | 4 +- Werkout_ios/UserStore.swift | 24 ++++ .../Views/AllWorkouts/AllWorkoutsView.swift | 117 +++++++++++++++--- Werkout_ios/Views/PlanWorkoutView.swift | 95 ++++++++++++++ .../WorkoutDetail/WorkoutDetailView.swift | 22 +++- 14 files changed, 535 insertions(+), 24 deletions(-) create mode 100644 Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_ios.xcscheme create mode 100644 Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_watch Watch App.xcscheme create mode 100644 Werkout_ios/APIModels/PlannedWorkout.swift create mode 100644 Werkout_ios/JSON/PlannedWorkouts.json create mode 100644 Werkout_ios/Views/PlanWorkoutView.swift diff --git a/Werkout_ios.xcodeproj/project.pbxproj b/Werkout_ios.xcodeproj/project.pbxproj index 01d277b..88bf8f3 100644 --- a/Werkout_ios.xcodeproj/project.pbxproj +++ b/Werkout_ios.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 1C485C8C2A49D65600A6F896 /* WorkoutHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */; }; 1C485C8D2A49D95700A6F896 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A822A42347D0042FFBD /* Extensions.swift */; }; 1C6D0A372A4BE9A500D98B06 /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C6D0A362A4BE9A500D98B06 /* VideoPlayerView.swift */; }; + 1CAF4D8A2A5132F900B00E50 /* PlannedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CAF4D892A5132F900B00E50 /* PlannedWorkout.swift */; }; + 1CAF4D8C2A51339200B00E50 /* PlannedWorkouts.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CAF4D8B2A51339200B00E50 /* PlannedWorkouts.json */; }; + 1CAF4D952A52180600B00E50 /* PlanWorkoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */; }; 1CF65A262A3972840042FFBD /* Werkout_iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */; }; 1CF65A282A3972840042FFBD /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A272A3972840042FFBD /* Persistence.swift */; }; 1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */; }; @@ -107,6 +110,9 @@ 1C6D0A3C2A4BEC9700D98B06 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS9.4.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; }; 1C6D0A3D2A4BEC9700D98B06 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS9.4.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; 1C6D0A402A4BECA400D98B06 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; }; + 1CAF4D892A5132F900B00E50 /* PlannedWorkout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlannedWorkout.swift; sourceTree = ""; }; + 1CAF4D8B2A51339200B00E50 /* PlannedWorkouts.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = PlannedWorkouts.json; sourceTree = ""; }; + 1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanWorkoutView.swift; sourceTree = ""; }; 1CF65A222A3972840042FFBD /* Werkout_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Werkout_ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_iosApp.swift; sourceTree = ""; }; 1CF65A272A3972840042FFBD /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; @@ -264,6 +270,7 @@ 1CF65A5A2A3BF4BE0042FFBD /* Equipment.swift */, 1CF65A442A39FB550042FFBD /* Exercise.swift */, 1CF65A582A3BF4B60042FFBD /* Muscle.swift */, + 1CAF4D892A5132F900B00E50 /* PlannedWorkout.swift */, 1CF65A462A39FB6C0042FFBD /* RegisteredUser.swift */, 1CF65A422A39FB410042FFBD /* Workout.swift */, ); @@ -275,6 +282,7 @@ children = ( 1CF65A3B2A3972CE0042FFBD /* ExternalWorkoutDetailView.swift */, 1CF65A2C2A3972840042FFBD /* MainView.swift */, + 1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */, 1C6D0A362A4BE9A500D98B06 /* VideoPlayerView.swift */, 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */, 1CF65A8B2A44B7590042FFBD /* AccountView */, @@ -298,6 +306,7 @@ 1CF65A662A3BFF840042FFBD /* Exercises.json */, 1CF65ABB2A4897E20042FFBD /* RegisteredUser.json */, 1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */, + 1CAF4D8B2A51339200B00E50 /* PlannedWorkouts.json */, ); path = JSON; sourceTree = ""; @@ -470,6 +479,7 @@ 1CF65ABC2A4897E20042FFBD /* RegisteredUser.json in Resources */, 1CF65A672A3BFF840042FFBD /* Exercises.json in Resources */, 1CF65A572A3BF3830042FFBD /* AllMuscles.json in Resources */, + 1CAF4D8C2A51339200B00E50 /* PlannedWorkouts.json in Resources */, 1CF65A542A3A9AF30042FFBD /* Straight_Leg_Sit_Up.mp4 in Resources */, 1CF65A2F2A3972850042FFBD /* Assets.xcassets in Resources */, 1CF65A872A4400E10042FFBD /* ToDo in Resources */, @@ -517,6 +527,7 @@ 1CF65A432A39FB410042FFBD /* Workout.swift in Sources */, 1CF65A502A3A1EA90042FFBD /* BridgeModule.swift in Sources */, 1CF65A592A3BF4B60042FFBD /* Muscle.swift in Sources */, + 1CAF4D8A2A5132F900B00E50 /* PlannedWorkout.swift in Sources */, 1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */, 1CF65A2D2A3972840042FFBD /* MainView.swift in Sources */, 1CF65A7D2A41275D0042FFBD /* Network.swift in Sources */, @@ -526,6 +537,7 @@ 1CF65A282A3972840042FFBD /* Persistence.swift in Sources */, 1CF65ABA2A4894430042FFBD /* UserStore.swift in Sources */, 1C485C8C2A49D65600A6F896 /* WorkoutHistoryView.swift in Sources */, + 1CAF4D952A52180600B00E50 /* PlanWorkoutView.swift in Sources */, 1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */, 1CF65A452A39FB550042FFBD /* Exercise.swift in Sources */, 1CF65A612A3BF6020042FFBD /* AddExerciseView.swift in Sources */, diff --git a/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_ios.xcscheme b/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_ios.xcscheme new file mode 100644 index 0000000..c9bf622 --- /dev/null +++ b/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_ios.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_watch Watch App.xcscheme b/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_watch Watch App.xcscheme new file mode 100644 index 0000000..9d13ec2 --- /dev/null +++ b/Werkout_ios.xcodeproj/xcshareddata/xcschemes/Werkout_watch Watch App.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Werkout_ios.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist b/Werkout_ios.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist index e5584d3..78dfc75 100644 --- a/Werkout_ios.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Werkout_ios.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist @@ -15,5 +15,18 @@ 0 + SuppressBuildableAutocreation + + 1CF65A212A3972840042FFBD + + primary + + + 1CF65A922A452D270042FFBD + + primary + + + diff --git a/Werkout_ios/APIModels/PlannedWorkout.swift b/Werkout_ios/APIModels/PlannedWorkout.swift new file mode 100644 index 0000000..aecc8b4 --- /dev/null +++ b/Werkout_ios/APIModels/PlannedWorkout.swift @@ -0,0 +1,29 @@ +// +// PlannedWorkout.swift +// Werkout_ios +// +// Created by Trey Tartt on 7/1/23. +// + +import Foundation + +struct PlannedWorkout: Codable { + let id: Int + let createdAt, updatedAt, onDate: String + let workout: Workout + + enum CodingKeys: String, CodingKey { + case id + case createdAt = "created_at" + case updatedAt = "updated_at" + case onDate = "on_date" + case workout + } + + var date: Date? { + let df = DateFormatter() + df.dateFormat = "yyyy-MM-dd" + df.locale = Locale(identifier: "en_US_POSIX") + return df.date(from: self.onDate) + } +} diff --git a/Werkout_ios/DataStore.swift b/Werkout_ios/DataStore.swift index 7955d12..da83411 100644 --- a/Werkout_ios/DataStore.swift +++ b/Werkout_ios/DataStore.swift @@ -6,8 +6,9 @@ // import Foundation +import SwiftUI -class DataStore { +class DataStore: ObservableObject { enum DataStoreStatus { case loading case idle @@ -20,10 +21,10 @@ class DataStore { public private(set) var allEquipment: [Equipment]? public private(set) var allExercise: [ExerciseExercise]? - public private(set) var status = DataStoreStatus.idle + @Published public private(set) var status = DataStoreStatus.idle private let fetchAllDataQueue = DispatchGroup() - + public func fetchAllData() { status = .loading diff --git a/Werkout_ios/Extensions.swift b/Werkout_ios/Extensions.swift index 305408d..856a391 100644 --- a/Werkout_ios/Extensions.swift +++ b/Werkout_ios/Extensions.swift @@ -45,6 +45,13 @@ extension String { df.locale = Locale(identifier: "en_US_POSIX") return df.date(from: self) } + + var plannedDate: Date? { + let df = DateFormatter() + df.dateFormat = "yyyy-MM-dd" + df.locale = Locale(identifier: "en_US_POSIX") + return df.date(from: self) + } } extension Date { @@ -55,4 +62,32 @@ extension Date { func get(_ component: Calendar.Component, calendar: Calendar = Calendar.current) -> Int { return calendar.component(component, from: self) } + + var formatForPlannedWorkout: String { + let df = DateFormatter() + df.dateFormat = "yyyy-MM-dd" + df.locale = Locale(identifier: "en_US_POSIX") + return df.string(from: self) + } + + var weekDay: String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "EEE" + let weekDay = dateFormatter.string(from: self) + return weekDay + } + + var monthString: String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "MMM" + let weekDay = dateFormatter.string(from: self) + return weekDay + } + + var dateString: String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "d" + let weekDay = dateFormatter.string(from: self) + return weekDay + } } diff --git a/Werkout_ios/JSON/PlannedWorkouts.json b/Werkout_ios/JSON/PlannedWorkouts.json new file mode 100644 index 0000000..2633bd1 --- /dev/null +++ b/Werkout_ios/JSON/PlannedWorkouts.json @@ -0,0 +1,16 @@ +[ + { + "id": 1, + "created_at": "2023-07-02T04:16:34.262272Z", + "updated_at": "2023-07-02T04:16:34.262315Z", + "on_date": "2023-07-02", + "workout": { + "id": 22, + "created_at": "2023-06-26T02:53:56.101972Z", + "updated_at": "2023-06-26T02:53:56.106136Z", + "name": "Aaaa", + "description": "description", + "registered_user": 1 + } + } +] diff --git a/Werkout_ios/Network/Fetchables.swift b/Werkout_ios/Network/Fetchables.swift index a0c991b..816c3a0 100644 --- a/Werkout_ios/Network/Fetchables.swift +++ b/Werkout_ios/Network/Fetchables.swift @@ -41,6 +41,11 @@ class CompletedWorkoutFetchable: Fetchable { var endPoint: String = "/workout/completed/" } +class PlannedWorkoutFetchable: Fetchable { + typealias Response = [PlannedWorkout] + var endPoint: String = "/workout/planned_workouts/" +} + class CreateWorkoutFetchable: Postable { var postableData: [String : Any]? var successStatus = 201 @@ -80,3 +85,15 @@ class LoginFetchable: Postable { self.postableData = postData } } + +class PlanWorkoutFetchable: Postable { + var postableData: [String : Any]? + var successStatus = 201 + + typealias Response = RegisteredUser + var endPoint: String = "/workout/plan_workout/" + + init(postData: [String: Any]) { + self.postableData = postData + } +} diff --git a/Werkout_ios/Network/Network.swift b/Werkout_ios/Network/Network.swift index 1a35b07..b31cb23 100644 --- a/Werkout_ios/Network/Network.swift +++ b/Werkout_ios/Network/Network.swift @@ -8,7 +8,7 @@ import Foundation enum BaseURLs: String { - case local = "http://127.0.0.1:8000/" + case local = "http://127.0.0.1:8000" case dev = "https://dev.werkout.fitness" } @@ -37,7 +37,7 @@ protocol Postable: Fetchable { extension Fetchable { var baseURL: String { - BaseURLs.dev.rawValue + BaseURLs.local.rawValue } var attachToken: Bool { diff --git a/Werkout_ios/UserStore.swift b/Werkout_ios/UserStore.swift index ea0e4e3..d468e0e 100644 --- a/Werkout_ios/UserStore.swift +++ b/Werkout_ios/UserStore.swift @@ -13,6 +13,8 @@ class UserStore: ObservableObject { @Published public private(set) var registeredUser: RegisteredUser? + var plannedWorkouts = [PlannedWorkout]() + init(registeredUser: RegisteredUser? = nil) { self.registeredUser = registeredUser if let data = UserDefaults.standard.data(forKey: UserStore.userDefaultsRegisteredUserKey), @@ -53,4 +55,26 @@ class UserStore: ObservableObject { func setFakeUser() { self.registeredUser = PreviewData.parseRegisterdUser() } + + func fetchPlannedWorkouts() { + PlannedWorkoutFetchable().fetch(completion: { result in + switch result { + case .success(let models): + self.plannedWorkouts = models + case .failure(let failure): + fatalError("shit broke") + } + }) + } + + func plannedWorkoutFor(date: Date) -> PlannedWorkout? { + for plannedWorkout in plannedWorkouts { + if let plannedworkoutDate = plannedWorkout.date { + if Calendar.current.isDate(date, equalTo: plannedworkoutDate, toGranularity: .day) { + return plannedWorkout + } + } + } + return nil + } } diff --git a/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift b/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift index 61f68c8..e43fa3f 100644 --- a/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift +++ b/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift @@ -9,10 +9,27 @@ 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 { @@ -22,27 +39,32 @@ struct AllWorkoutsView: View { } @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, - let _ = DataStore.shared.allExercise, - let _ = DataStore.shared.allMuscles, - let _ = DataStore.shared.allEquipment { - List { - ForEach(workouts, id:\.name) { workout in - VStack { - Text(workout.name) - .font(.title2) - .frame(maxWidth: .infinity, alignment: .leading) - Text(workout.description ?? "") - .frame(maxWidth: .infinity, alignment: .leading) + 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) + } } - .contentShape(Rectangle()) - .onTapGesture { - selectedWorkout = workout + .pickerStyle(.segmented) + .padding() + + switch selectedSegment { + case .AllWorkout: + allWorkoutView(workouts: workouts) + case .MyWorkouts: + plannedWorkout(workouts: UserStore.shared.plannedWorkouts) } } } @@ -51,6 +73,7 @@ struct AllWorkoutsView: View { .progressViewStyle(.circular) } }.onAppear{ +// UserStore.shared.logout() maybeUpdateShit() } .sheet(item: $selectedWorkout) { item in @@ -69,10 +92,70 @@ struct AllWorkoutsView: View { } } + func allWorkoutView(workouts: [Workout]) -> some View { + List { + ForEach(workouts, id:\.name) { workout in + VStack { + Text(workout.name) + .font(.title2) + .frame(maxWidth: .infinity, alignment: .leading) + Text(workout.description ?? "") + .frame(maxWidth: .infinity, alignment: .leading) + } + .contentShape(Rectangle()) + .onTapGesture { + selectedWorkout = workout + } + } + } + } + + 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 { + } + } + } + } + } + func maybeUpdateShit() { if UserStore.shared.token != nil{ + if UserStore.shared.plannedWorkouts.isEmpty { + UserStore.shared.fetchPlannedWorkouts() + } + if needsUpdating { - DataStore.shared.fetchAllData() + dataStore.fetchAllData() AllWorkoutFetchable().fetch(completion: { result in needsUpdating = false diff --git a/Werkout_ios/Views/PlanWorkoutView.swift b/Werkout_ios/Views/PlanWorkoutView.swift new file mode 100644 index 0000000..6bdc440 --- /dev/null +++ b/Werkout_ios/Views/PlanWorkoutView.swift @@ -0,0 +1,95 @@ +// +// PlanWorkoutView.swift +// Werkout_ios +// +// Created by Trey Tartt on 7/2/23. +// + +import SwiftUI + +struct PlanWorkoutView: View { + @State var selectedDate = Date() + let workout: Workout + @Environment(\.dismiss) var dismiss + var addedPlannedWorkout: (() -> Void)? + + var body: some View { + VStack() { + Text(workout.name) + .font(.title) + + Text(selectedDate.formatted(date: .abbreviated, time: .omitted)) + .font(.system(size: 28)) + .bold() + .foregroundColor(Color.accentColor) + .padding() + .animation(.spring(), value: selectedDate) + .frame(width: 500) + + Divider().frame(height: 1) + + DatePicker("Select Date", selection: $selectedDate, displayedComponents: [.date]) + .padding(.horizontal) + .datePickerStyle(.graphical) + + Divider() + + HStack { + Button(action: { + planWorkout() + }, label: { + Image(systemName: "plus.app") + .font(.title) + .frame(maxWidth: .infinity, maxHeight: .infinity) + }) + .frame(maxWidth: .infinity, alignment: .center) + .frame(height: 44) + .foregroundColor(.blue) + .background(.yellow) + .cornerRadius(8) + .padding() + + Button(action: { + dismiss() + }, label: { + Image(systemName: "xmark.octagon.fill") + .font(.title) + .frame(maxWidth: .infinity, maxHeight: .infinity) + }) + .frame(maxWidth: .infinity, alignment: .center) + .frame(height: 44) + .foregroundColor(.white) + .background(.red) + .cornerRadius(8) + .padding() + } + + Spacer() + } + .padding() + } + + func planWorkout() { + let postData = [ + "on_date": selectedDate.formatForPlannedWorkout, + "workout": workout.id + ] as [String : Any] + + PlanWorkoutFetchable(postData: postData).fetch(completion: { result in + switch result { + case .success(_): + UserStore.shared.fetchPlannedWorkouts() + dismiss() + addedPlannedWorkout?() + case .failure(_): + fatalError("shit broke") + } + }) + } +} + +struct PlanWorkoutView_Previews: PreviewProvider { + static var previews: some View { + PlanWorkoutView(workout: PreviewData.workout()) + } +} diff --git a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift index 04fd140..8c2a01e 100644 --- a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift +++ b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift @@ -18,6 +18,7 @@ struct WorkoutDetailView: View { } @State var presentedSheet: Sheet? + @State var workoutToPlan: Workout? var body: some View { ZStack { @@ -35,6 +36,8 @@ struct WorkoutDetailView: View { ActionsView(completedWorkout: { bridgeModule.workoutEndDate = Date() bridgeModule.sendWorkoutCompleteToWatch() + }, planWorkout: { workout in + workoutToPlan = workout }, workout: workout) .frame(height: 44) @@ -49,6 +52,11 @@ struct WorkoutDetailView: View { }) } } + .sheet(item: $workoutToPlan) { workout in + PlanWorkoutView(workout: workout, addedPlannedWorkout: { + dismiss() + }) + } .interactiveDismissDisabled() } } @@ -107,6 +115,7 @@ struct InfoView: View { struct ActionsView: View { @ObservedObject var bridgeModule = BridgeModule.shared var completedWorkout: (() -> Void)? + var planWorkout: ((Workout) -> Void)? var workout: Workout @Environment(\.dismiss) var dismiss @@ -126,6 +135,17 @@ struct ActionsView: View { .background(.red) .foregroundColor(.white) + Button(action: { + planWorkout?(workout) + }, label: { + Image(systemName: "calendar.badge.plus") + .font(.title) + .frame(maxWidth: .infinity, maxHeight: .infinity) + }) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.blue) + .foregroundColor(.white) + Button(action: { startWorkout() }, label: { @@ -162,8 +182,6 @@ struct ActionsView: View { } } - - func nextExercise() { bridgeModule.nextExercise() }