diff --git a/Werkout_ios.xcodeproj/project.pbxproj b/Werkout_ios.xcodeproj/project.pbxproj index b2899a5..1defcc8 100644 --- a/Werkout_ios.xcodeproj/project.pbxproj +++ b/Werkout_ios.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 1CF65A832A42347D0042FFBD /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A822A42347D0042FFBD /* Extensions.swift */; }; 1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */; }; 1CF65A872A4400E10042FFBD /* ToDo in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A862A4400E10042FFBD /* ToDo */; }; + 1CF65A8E2A44B78B0042FFBD /* CompletedWorkoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -83,6 +84,7 @@ 1CF65A822A42347D0042FFBD /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkout.swift; sourceTree = ""; }; 1CF65A862A4400E10042FFBD /* ToDo */ = {isa = PBXFileReference; lastKnownFileType = text; path = ToDo; sourceTree = ""; }; + 1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkoutView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -122,6 +124,7 @@ 1CF65A272A3972840042FFBD /* Persistence.swift */, 1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */, 1CF65A3F2A3973840042FFBD /* Views */, + 1CF65A8B2A44B7590042FFBD /* AccountView */, 1CF65A3E2A39737D0042FFBD /* APIModels */, 1CF65A3D2A3973760042FFBD /* Network */, 1CF65A2E2A3972850042FFBD /* Assets.xcassets */, @@ -171,12 +174,11 @@ children = ( 1CF65A2C2A3972840042FFBD /* MainView.swift */, 1CF65A3B2A3972CE0042FFBD /* ExternalWorkoutDetailView.swift */, - 1CF65A622A3BF6A30042FFBD /* AllWorkoutsView.swift */, - 1CF65A4B2A39FDA20042FFBD /* WorkoutDetailView.swift */, - 1CF65A4D2A39FF200042FFBD /* WorkoutDetailViewModel.swift */, - 1CF65A6C2A3F60100042FFBD /* CreateWorkoutViews */, - 1CF65A602A3BF6020042FFBD /* AddExerciseView.swift */, - 1CF65A682A3C018F0042FFBD /* AccountView.swift */, + 1CF65A8A2A44B74D0042FFBD /* AddExercise */, + 1CF65A892A44B7390042FFBD /* AllWorkouts */, + 1CF65A8C2A44B7680042FFBD /* CompletedWorkout */, + 1CF65A6C2A3F60100042FFBD /* CreateWorkout */, + 1CF65A882A44B7290042FFBD /* WorkoutDetail */, ); path = Views; sourceTree = ""; @@ -193,7 +195,7 @@ path = JSON; sourceTree = ""; }; - 1CF65A6C2A3F60100042FFBD /* CreateWorkoutViews */ = { + 1CF65A6C2A3F60100042FFBD /* CreateWorkout */ = { isa = PBXGroup; children = ( 1CF65A6D2A3F60480042FFBD /* CreateViewModels.swift */, @@ -201,7 +203,48 @@ 1CF65A722A3F60D20042FFBD /* CreateExerciseActionsView.swift */, 1CF65A7A2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift */, ); - path = CreateWorkoutViews; + path = CreateWorkout; + sourceTree = ""; + }; + 1CF65A882A44B7290042FFBD /* WorkoutDetail */ = { + isa = PBXGroup; + children = ( + 1CF65A4B2A39FDA20042FFBD /* WorkoutDetailView.swift */, + 1CF65A4D2A39FF200042FFBD /* WorkoutDetailViewModel.swift */, + ); + path = WorkoutDetail; + sourceTree = ""; + }; + 1CF65A892A44B7390042FFBD /* AllWorkouts */ = { + isa = PBXGroup; + children = ( + 1CF65A622A3BF6A30042FFBD /* AllWorkoutsView.swift */, + ); + path = AllWorkouts; + sourceTree = ""; + }; + 1CF65A8A2A44B74D0042FFBD /* AddExercise */ = { + isa = PBXGroup; + children = ( + 1CF65A602A3BF6020042FFBD /* AddExerciseView.swift */, + ); + path = AddExercise; + sourceTree = ""; + }; + 1CF65A8B2A44B7590042FFBD /* AccountView */ = { + isa = PBXGroup; + children = ( + 1CF65A682A3C018F0042FFBD /* AccountView.swift */, + ); + path = AccountView; + sourceTree = ""; + }; + 1CF65A8C2A44B7680042FFBD /* CompletedWorkout */ = { + isa = PBXGroup; + children = ( + 1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */, + ); + path = CompletedWorkout; sourceTree = ""; }; /* End PBXGroup section */ @@ -295,6 +338,7 @@ 1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */, 1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */, 1CF65A4C2A39FDA20042FFBD /* WorkoutDetailView.swift in Sources */, + 1CF65A8E2A44B78B0042FFBD /* CompletedWorkoutView.swift in Sources */, 1CF65A432A39FB410042FFBD /* Workout.swift in Sources */, 1CF65A502A3A1EA90042FFBD /* BridgeModule.swift in Sources */, 1CF65A592A3BF4B60042FFBD /* Muscle.swift in Sources */, diff --git a/Werkout_ios/Views/AccountView.swift b/Werkout_ios/AccountView/AccountView.swift similarity index 100% rename from Werkout_ios/Views/AccountView.swift rename to Werkout_ios/AccountView/AccountView.swift diff --git a/Werkout_ios/Network/Network.swift b/Werkout_ios/Network/Network.swift index 0cef1ed..3c34284 100644 --- a/Werkout_ios/Network/Network.swift +++ b/Werkout_ios/Network/Network.swift @@ -13,7 +13,7 @@ enum FetchableError: Error { case decodeError(Error) case endOfFileError case noPostData - case statusError(Int) + case statusError(Int, String?) } protocol Fetchable { @@ -86,7 +86,12 @@ extension Postable { if let httpRespone = response as? HTTPURLResponse { if httpRespone.statusCode != 201 { - completion(.failure(.statusError(httpRespone.statusCode))) + var returnStr: String? + if let data = data { + returnStr = String(data: data, encoding: .utf8) + } + + completion(.failure(.statusError(httpRespone.statusCode, returnStr))) return } } diff --git a/Werkout_ios/Views/AddExerciseView.swift b/Werkout_ios/Views/AddExercise/AddExerciseView.swift similarity index 100% rename from Werkout_ios/Views/AddExerciseView.swift rename to Werkout_ios/Views/AddExercise/AddExerciseView.swift diff --git a/Werkout_ios/Views/AllWorkoutsView.swift b/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift similarity index 100% rename from Werkout_ios/Views/AllWorkoutsView.swift rename to Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift diff --git a/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift b/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift new file mode 100644 index 0000000..d11e964 --- /dev/null +++ b/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift @@ -0,0 +1,103 @@ +// +// CompletedWorkoutView.swift +// Werkout_ios +// +// Created by Trey Tartt on 6/22/23. +// + +import SwiftUI + +struct CompletedWorkoutView: View { + @ObservedObject var bridgeModule = BridgeModule.shared + var postData: [String: Any] + let workout: Workout + @Environment(\.dismiss) var dismiss + + @State var difficulty: Float = 0 + @State var notes: String = "" + let completedWorkoutDismissed: ((Bool) -> Void)? + + var body: some View { + VStack { + Text(workout.name) + .frame(maxWidth: .infinity, alignment: .leading) + .font(.title3) + .padding(.top + ) + if let desc = workout.description { + Text(desc) + .frame(maxWidth: .infinity, alignment: .leading) + .font(.body) + .padding(.top) + + } + + Divider() + + Text("how hard was this shit") + + HStack { + Text("easy") + Spacer() + Text("Death") + } + + Slider(value: $difficulty, in: 0...5, step: 1) + + Divider() + + TextField("Notes", text: $notes) + +// Divider() + + Spacer() + + Button("Upload", action: { + upload(postBody: postData) + }) + .frame(maxWidth: .infinity, alignment: .center) + .frame(height: 44) + .foregroundColor(.blue) + .background(.yellow) + .cornerRadius(8) + .padding() + .frame(maxWidth: .infinity) + } + .padding([.leading, .trailing]) + } + + func upload(postBody: [String: Any]) { + var _postBody = postBody + _postBody["difficulty"] = difficulty + _postBody["notes"] = notes + + + CompleteWorkoutFetchable(postData: _postBody).fetch(completion: { result in + switch result { + case .success(_): + DispatchQueue.main.async { + bridgeModule.resetCurrentWorkout() + dismiss() + completedWorkoutDismissed?(true) + } + case .failure(let failure): + print(failure) + } + }) + } +} + +//struct CompletedWorkoutView_Previews: PreviewProvider { +// static let postBody = [ +// "difficulty": 1, +// "workout_start_time": Date().timeFormatForUpload, +// "workout": 1, +// "total_time": 140 +// ] as [String : Any] +// +// static let workout = PreviewWorkout.workout() +// +// static var previews: some View { +// CompletedWorkoutView(postData: CompletedWorkoutView_Previews.postBody, workout: workout) +// } +//} diff --git a/Werkout_ios/Views/CreateWorkoutViews/CreateExerciseActionsView.swift b/Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift similarity index 100% rename from Werkout_ios/Views/CreateWorkoutViews/CreateExerciseActionsView.swift rename to Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift diff --git a/Werkout_ios/Views/CreateWorkoutViews/CreateViewModels.swift b/Werkout_ios/Views/CreateWorkout/CreateViewModels.swift similarity index 100% rename from Werkout_ios/Views/CreateWorkoutViews/CreateViewModels.swift rename to Werkout_ios/Views/CreateWorkout/CreateViewModels.swift diff --git a/Werkout_ios/Views/CreateWorkoutViews/CreateWorkoutMainView.swift b/Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift similarity index 100% rename from Werkout_ios/Views/CreateWorkoutViews/CreateWorkoutMainView.swift rename to Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift diff --git a/Werkout_ios/Views/CreateWorkoutViews/CreateWorkoutSupersetActionsView.swift b/Werkout_ios/Views/CreateWorkout/CreateWorkoutSupersetActionsView.swift similarity index 100% rename from Werkout_ios/Views/CreateWorkoutViews/CreateWorkoutSupersetActionsView.swift rename to Werkout_ios/Views/CreateWorkout/CreateWorkoutSupersetActionsView.swift diff --git a/Werkout_ios/Views/WorkoutDetailView.swift b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift similarity index 84% rename from Werkout_ios/Views/WorkoutDetailView.swift rename to Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift index 07b6333..aa998ab 100644 --- a/Werkout_ios/Views/WorkoutDetailView.swift +++ b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift @@ -12,6 +12,13 @@ struct WorkoutDetailView: View { var bridgeModule = BridgeModule.shared @Environment(\.dismiss) var dismiss + enum Sheet: Identifiable { + case completedWorkout([String: Any]) + var id: String { return UUID().uuidString } + } + + @State var presentedSheet: Sheet? + var body: some View { ZStack { switch viewModel.status { @@ -25,14 +32,45 @@ struct WorkoutDetailView: View { .padding(.top) CountdownView() ExerciseListView(workout: workout) - ActionsView(workout: workout) + ActionsView(completedWorkout: { + if let workoutData = createWorkoutData() { + presentedSheet = .completedWorkout(workoutData) + bridgeModule.resetCurrentWorkout() + } + + }, workout: workout) .frame(height: 44) } + .sheet(item: $presentedSheet) { item in + switch item { + case .completedWorkout(let data): + CompletedWorkoutView(postData: data, workout: workout, completedWorkoutDismissed: { uploaded in + if uploaded { + dismiss() + } + }) + } + } .interactiveDismissDisabled() } } } + + func createWorkoutData() -> [String:Any]? { + guard let workoutid = bridgeModule.currentWorkout?.id, + let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload else { + return nil + } + let postBody = [ + "difficulty": 1, + "workout_start_time": startTime, + "workout": workoutid, + "total_time": bridgeModule.currentWorkoutRunTimeInSeconds + ] as [String : Any] + + return postBody + } } struct InfoView: View { @@ -59,6 +97,8 @@ struct InfoView: View { struct ActionsView: View { @ObservedObject var bridgeModule = BridgeModule.shared + var completedWorkout: (() -> Void)? + var workout: Workout @Environment(\.dismiss) var dismiss @@ -100,7 +140,7 @@ struct ActionsView: View { .foregroundColor(.white) Button(action: { - completeWorkout() + completedWorkout?() }, label: { Image(systemName: "checkmark") .font(.title) @@ -113,30 +153,7 @@ struct ActionsView: View { } } - func completeWorkout() { - guard let workoutid = bridgeModule.currentWorkout?.id, - let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload else { - return - } - let postBody = [ - "difficulty": 1, - "workout_start_time": startTime, - "workout": workoutid, - "total_time": bridgeModule.currentWorkoutRunTimeInSeconds - ] as [String : Any] - - CompleteWorkoutFetchable(postData: postBody).fetch(completion: { result in - switch result { - case .success(_): - DispatchQueue.main.async { - bridgeModule.resetCurrentWorkout() - dismiss() - } - case .failure(let failure): - print(failure) - } - }) - } + func nextExercise() { bridgeModule.nextExercise() diff --git a/Werkout_ios/Views/WorkoutDetailViewModel.swift b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailViewModel.swift similarity index 100% rename from Werkout_ios/Views/WorkoutDetailViewModel.swift rename to Werkout_ios/Views/WorkoutDetail/WorkoutDetailViewModel.swift