This commit is contained in:
Trey t
2023-06-25 10:59:20 -05:00
parent 01915752b6
commit 24ee992f93
14 changed files with 448 additions and 727 deletions

View File

@@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1C485C832A489B9C00A6F896 /* CompletedWorkouts.json in Resources */ = {isa = PBXBuildFile; fileRef = 1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */; };
1CF65A262A3972840042FFBD /* Werkout_iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A252A3972840042FFBD /* Werkout_iosApp.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 */; }; 1CF65A282A3972840042FFBD /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A272A3972840042FFBD /* Persistence.swift */; };
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */; }; 1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */; };
@@ -64,6 +65,8 @@
1CF65AB32A452F360042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; }; 1CF65AB32A452F360042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; };
1CF65AB42A4530200042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; }; 1CF65AB42A4530200042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; };
1CF65AB62A4532940042FFBD /* WatchMainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */; }; 1CF65AB62A4532940042FFBD /* WatchMainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */; };
1CF65ABA2A4894430042FFBD /* UserStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB92A4894430042FFBD /* UserStore.swift */; };
1CF65ABC2A4897E20042FFBD /* RegisteredUser.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65ABB2A4897E20042FFBD /* RegisteredUser.json */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -91,6 +94,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = CompletedWorkouts.json; sourceTree = "<group>"; };
1CF65A222A3972840042FFBD /* Werkout_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Werkout_ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; }; 1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_iosApp.swift; sourceTree = "<group>"; };
1CF65A272A3972840042FFBD /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; }; 1CF65A272A3972840042FFBD /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
@@ -139,6 +143,8 @@
1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchMainViewModel.swift; sourceTree = "<group>"; }; 1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchMainViewModel.swift; sourceTree = "<group>"; };
1CF65AB72A4534DC0042FFBD /* Werkout_watch Watch App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Werkout_watch Watch App.entitlements"; sourceTree = "<group>"; }; 1CF65AB72A4534DC0042FFBD /* Werkout_watch Watch App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Werkout_watch Watch App.entitlements"; sourceTree = "<group>"; };
1CF65AB82A45387B0042FFBD /* Werkout-watch-Watch-App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Werkout-watch-Watch-App-Info.plist"; sourceTree = SOURCE_ROOT; }; 1CF65AB82A45387B0042FFBD /* Werkout-watch-Watch-App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Werkout-watch-Watch-App-Info.plist"; sourceTree = SOURCE_ROOT; };
1CF65AB92A4894430042FFBD /* UserStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserStore.swift; sourceTree = "<group>"; };
1CF65ABB2A4897E20042FFBD /* RegisteredUser.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = RegisteredUser.json; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -187,6 +193,8 @@
1CF65A822A42347D0042FFBD /* Extensions.swift */, 1CF65A822A42347D0042FFBD /* Extensions.swift */,
1CF65A272A3972840042FFBD /* Persistence.swift */, 1CF65A272A3972840042FFBD /* Persistence.swift */,
1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */, 1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */,
1CF65A802A412AA30042FFBD /* DataStore.swift */,
1CF65AB92A4894430042FFBD /* UserStore.swift */,
1CF65A3F2A3973840042FFBD /* Views */, 1CF65A3F2A3973840042FFBD /* Views */,
1CF65A8B2A44B7590042FFBD /* AccountView */, 1CF65A8B2A44B7590042FFBD /* AccountView */,
1CF65A3E2A39737D0042FFBD /* APIModels */, 1CF65A3E2A39737D0042FFBD /* APIModels */,
@@ -195,7 +203,6 @@
1CF65A302A3972850042FFBD /* Werkout_ios.entitlements */, 1CF65A302A3972850042FFBD /* Werkout_ios.entitlements */,
1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */, 1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */,
1CF65A312A3972850042FFBD /* Preview Content */, 1CF65A312A3972850042FFBD /* Preview Content */,
1CF65A802A412AA30042FFBD /* DataStore.swift */,
1CF65A862A4400E10042FFBD /* ToDo */, 1CF65A862A4400E10042FFBD /* ToDo */,
); );
path = Werkout_ios; path = Werkout_ios;
@@ -223,12 +230,12 @@
1CF65A3E2A39737D0042FFBD /* APIModels */ = { 1CF65A3E2A39737D0042FFBD /* APIModels */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1CF65A422A39FB410042FFBD /* Workout.swift */,
1CF65A442A39FB550042FFBD /* Exercise.swift */,
1CF65A462A39FB6C0042FFBD /* RegisteredUser.swift */,
1CF65A582A3BF4B60042FFBD /* Muscle.swift */,
1CF65A5A2A3BF4BE0042FFBD /* Equipment.swift */,
1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */, 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */,
1CF65A5A2A3BF4BE0042FFBD /* Equipment.swift */,
1CF65A442A39FB550042FFBD /* Exercise.swift */,
1CF65A582A3BF4B60042FFBD /* Muscle.swift */,
1CF65A462A39FB6C0042FFBD /* RegisteredUser.swift */,
1CF65A422A39FB410042FFBD /* Workout.swift */,
); );
path = APIModels; path = APIModels;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -255,6 +262,8 @@
1CF65A562A3BF3830042FFBD /* AllMuscles.json */, 1CF65A562A3BF3830042FFBD /* AllMuscles.json */,
1CF65A5E2A3BF5A60042FFBD /* Equipment.json */, 1CF65A5E2A3BF5A60042FFBD /* Equipment.json */,
1CF65A662A3BFF840042FFBD /* Exercises.json */, 1CF65A662A3BFF840042FFBD /* Exercises.json */,
1CF65ABB2A4897E20042FFBD /* RegisteredUser.json */,
1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */,
); );
path = JSON; path = JSON;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -415,9 +424,11 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
1CF65A5F2A3BF5A60042FFBD /* Equipment.json in Resources */, 1CF65A5F2A3BF5A60042FFBD /* Equipment.json in Resources */,
1C485C832A489B9C00A6F896 /* CompletedWorkouts.json in Resources */,
1CF65A4A2A39FBB10042FFBD /* WorkoutOne.json in Resources */, 1CF65A4A2A39FBB10042FFBD /* WorkoutOne.json in Resources */,
1CF65A652A3BF6BE0042FFBD /* AllWorkouts.json in Resources */, 1CF65A652A3BF6BE0042FFBD /* AllWorkouts.json in Resources */,
1CF65A332A3972850042FFBD /* Preview Assets.xcassets in Resources */, 1CF65A332A3972850042FFBD /* Preview Assets.xcassets in Resources */,
1CF65ABC2A4897E20042FFBD /* RegisteredUser.json in Resources */,
1CF65A672A3BFF840042FFBD /* Exercises.json in Resources */, 1CF65A672A3BFF840042FFBD /* Exercises.json in Resources */,
1CF65A572A3BF3830042FFBD /* AllMuscles.json in Resources */, 1CF65A572A3BF3830042FFBD /* AllMuscles.json in Resources */,
1CF65A542A3A9AF30042FFBD /* Straight_Leg_Sit_Up.mp4 in Resources */, 1CF65A542A3A9AF30042FFBD /* Straight_Leg_Sit_Up.mp4 in Resources */,
@@ -472,6 +483,7 @@
1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */, 1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */,
1CF65A832A42347D0042FFBD /* Extensions.swift in Sources */, 1CF65A832A42347D0042FFBD /* Extensions.swift in Sources */,
1CF65A282A3972840042FFBD /* Persistence.swift in Sources */, 1CF65A282A3972840042FFBD /* Persistence.swift in Sources */,
1CF65ABA2A4894430042FFBD /* UserStore.swift in Sources */,
1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */, 1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */,
1CF65A452A39FB550042FFBD /* Exercise.swift in Sources */, 1CF65A452A39FB550042FFBD /* Exercise.swift in Sources */,
1CF65A612A3BF6020042FFBD /* AddExerciseView.swift in Sources */, 1CF65A612A3BF6020042FFBD /* AddExerciseView.swift in Sources */,

View File

@@ -9,18 +9,21 @@ import Foundation
struct CompletedWorkout: Codable { struct CompletedWorkout: Codable {
let id: Int let id: Int
let workout: Workout
let createdAt, updatedAt: String let createdAt, updatedAt: String
let difficulty, totalTime: Int let difficulty, totalTime: Int?
let workoutStartTime: String let workoutStartTime: String
let workout: Int let notes: String?
let totalCalories: Int?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case id case id, workout
case createdAt = "created_at" case createdAt = "created_at"
case updatedAt = "updated_at" case updatedAt = "updated_at"
case difficulty case difficulty
case totalTime = "total_time" case totalTime = "total_time"
case workoutStartTime = "workout_start_time" case workoutStartTime = "workout_start_time"
case workout case notes
case totalCalories = "total_calories"
} }
} }

View File

@@ -11,12 +11,15 @@ struct RegisteredUser: Codable {
let id: Int let id: Int
let firstName, lastName, image: String? let firstName, lastName, image: String?
let nickName: String? let nickName: String?
let token: String?
let email: String?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case id case id
case firstName = "first_name" case firstName = "first_name"
case lastName = "last_name" case lastName = "last_name"
case image case image, token
case email = "email_address"
case nickName = "nick_name" case nickName = "nick_name"
} }
} }

View File

@@ -9,7 +9,59 @@ import Foundation
import SwiftUI import SwiftUI
struct AccountView: View { struct AccountView: View {
@State var completedWorkouts: [CompletedWorkout]?
@ObservedObject var userStore = UserStore.shared
var body: some View { var body: some View {
Text("account view") VStack {
if let registeredUser = userStore.registeredUser {
VStack(spacing: 10) {
if let nickName = registeredUser.nickName {
Text(nickName)
.font(.title)
}
HStack {
Text(registeredUser.firstName ?? "-")
Text(registeredUser.lastName ?? "-")
}
if let email = registeredUser.email {
Text(email)
}
}
}
if let completedWorkouts = completedWorkouts {
Text("\(completedWorkouts.count)")
}
Spacer()
}
.onAppear{
// fetchCompletedWorkouts()
}
}
func fetchCompletedWorkouts() {
CompletedWorkoutFetchable().fetch(completion: { result in
switch result {
case .success(let model):
completedWorkouts = model
case .failure(let failure):
fatalError(failure.localizedDescription)
}
})
}
}
struct AccountView_Previews: PreviewProvider {
static let userStore = UserStore.shared
static let completedWorkouts = PreviewWorkout.parseCompletedWorkouts()
static var previews: some View {
AccountView(completedWorkouts: completedWorkouts)
.onAppear{
userStore.setFakeUser()
}
} }
} }

View File

@@ -0,0 +1,26 @@
[
{
"id": 11,
"workout": {
"id": 21,
"registered_user": {
"id": 2,
"first_name": "test2_first",
"last_name": "test2_last",
"image": "",
"nick_name": null
},
"created_at": "2023-06-20T21:03:00.124080Z",
"updated_at": "2023-06-20T21:03:00.125595Z",
"name": "Ipad",
"description": "description"
},
"created_at": "2023-06-24T04:24:18.564094Z",
"updated_at": "2023-06-24T04:24:18.567762Z",
"difficulty": 1,
"total_time": 112,
"workout_start_time": "2015-10-22T19:50:08Z",
"notes": "free",
"total_calories": 123.0
}
]

View File

@@ -0,0 +1,11 @@
{
"id": 1,
"email_address": "user1@user1.com",
"created_at": "2023-06-11T22:09:52.419314Z",
"updated_at": "2023-06-11T22:09:52.419342Z",
"first_name": "test1_fist",
"last_name": "test1_last",
"image": "",
"nick_name": "NickkkkName",
"token": "8f10a5b8c7532f7f8602193767b46a2625a85c52"
}

View File

@@ -1,735 +1,181 @@
{ {
"name": "Sample Workou 1", "id": 20,
"description": "thot workout", "name": "Adsfadfafa",
"description": "description",
"exercises": [ "exercises": [
{ {
"workout": 4, "workout": 20,
"exercise": { "exercise": {
"id": 790, "id": 992,
"muscles": [ "muscles": [
{ {
"id": 9368, "id": 7270,
"created_at": "2023-06-14T17:05:42.321949Z", "created_at": "2023-06-14T17:05:39.769351Z",
"updated_at": "2023-06-14T17:05:42.322466Z", "updated_at": "2023-06-14T17:05:39.769758Z",
"exercise": 790, "exercise": 992,
"muscle": 3
},
{
"id": 9369,
"created_at": "2023-06-14T17:05:42.323207Z",
"updated_at": "2023-06-14T17:05:42.323633Z",
"exercise": 790,
"muscle": 2
}
],
"equipment": [
{
"id": 1856,
"created_at": "2023-06-13T02:28:05.326753Z",
"updated_at": "2023-06-13T02:28:05.327125Z",
"exercise": 790,
"equipment": 1089
}
],
"audio_url": "/media/exercise_audio/Sprinter_Crunch.m4a",
"video_url": "/media/exercise_videos/Sprinter_Crunch.mp4",
"created_at": "2023-06-11T22:50:19.125036Z",
"updated_at": "2023-06-11T22:50:19.125042Z",
"name": "Sprinter Crunch",
"description": "With arms overhead and feet on the floor, crunch up off the floor and bring your elbow and opposite knee together. Unfold and switch sides",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": true,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": true,
"joints_used": "hip,shoulder,knee,lumbar spine,thoracic spine,elbow",
"movement_patterns": "core,core - rotational",
"equipment_required": "Yoga Mat",
"muscle_groups": "obliques,core",
"synonyms": ""
},
"weight": null,
"reps": null,
"duration": 35,
"duration_audio": "/media/quantities_audio/for_35_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-12T02:11:42.925404Z"
},
{
"workout": 4,
"exercise": {
"id": 798,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 15,
"duration_audio": "/media/quantities_audio/for_15_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-12T02:11:42.929292Z"
},
{
"workout": 4,
"exercise": {
"id": 603,
"muscles": [
{
"id": 8193,
"created_at": "2023-06-14T17:05:40.908270Z",
"updated_at": "2023-06-14T17:05:40.908685Z",
"exercise": 603,
"muscle": 2
}
],
"equipment": [
{
"id": 1362,
"created_at": "2023-06-13T02:28:04.775223Z",
"updated_at": "2023-06-13T02:28:04.775809Z",
"exercise": 603,
"equipment": 1089
}
],
"audio_url": "/media/exercise_audio/High_Plank.m4a",
"video_url": "/media/exercise_videos/High_Plank.mp4",
"created_at": "2023-06-11T22:50:19.053321Z",
"updated_at": "2023-06-11T22:50:19.053328Z",
"name": "High Plank",
"description": "Start with your hands directly under your shoulders while staying on the balls of your feet",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": true,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "shoulder,wrist,elbow,ankle",
"movement_patterns": "core,core - anti-extension",
"equipment_required": "Yoga Mat",
"muscle_groups": "core",
"synonyms": "Front Lean Rest"
},
"weight": null,
"reps": null,
"duration": 35,
"duration_audio": "/media/quantities_audio/for_35_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.946651Z"
},
{
"workout": 4,
"exercise": {
"id": 798,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 15,
"duration_audio": "/media/quantities_audio/for_15_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.946937Z"
},
{
"workout": 4,
"exercise": {
"id": 142,
"muscles": [
{
"id": 9137,
"created_at": "2023-06-14T17:05:42.053373Z",
"updated_at": "2023-06-14T17:05:42.053816Z",
"exercise": 142,
"muscle": 3
},
{
"id": 9138,
"created_at": "2023-06-14T17:05:42.054554Z",
"updated_at": "2023-06-14T17:05:42.055041Z",
"exercise": 142,
"muscle": 2
},
{
"id": 9139,
"created_at": "2023-06-14T17:05:42.055750Z",
"updated_at": "2023-06-14T17:05:42.056176Z",
"exercise": 142,
"muscle": 29
}
],
"equipment": [
{
"id": 1760,
"created_at": "2023-06-13T02:28:05.211760Z",
"updated_at": "2023-06-13T02:28:05.212193Z",
"exercise": 142,
"equipment": 1091
}
],
"audio_url": "/media/exercise_audio/Single-Arm_Dumbbell_Suitcase_Carry.m4a",
"video_url": "/media/exercise_videos/Single-Arm_Dumbbell_Suitcase_Carry.mp4",
"created_at": "2023-06-11T22:50:18.866721Z",
"updated_at": "2023-06-11T22:50:18.866728Z",
"name": "Single-Arm Dumbbell Suitcase Carry",
"description": "Hold the dumbbell in your left hand.. Stay tall and keep your core tight,, as you walk forward.. Be careful not to lean to the side as you walk..",
"side": "left_arm",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": true,
"is_distance": true,
"is_duration": true,
"is_reps": false,
"joints_used": "ankle,lumbar spine,elbow,hip,knee,wrist",
"movement_patterns": "core,core - anti-lateral flexion,core - carry",
"equipment_required": "Dumbbell",
"muscle_groups": "obliques,core,forearms",
"synonyms": "Single Arm Dumbbell Suitcase Carry"
},
"weight": 30,
"reps": null,
"duration": 35,
"duration_audio": "/media/quantities_audio/for_35_seconds.m4a",
"weight_audio": "/media/quantities_audio/for_30_pounds.m4a",
"created_at": "2023-06-14T13:28:52.947120Z"
},
{
"workout": 4,
"exercise": {
"id": 370,
"muscles": [
{
"id": 9146,
"created_at": "2023-06-14T17:05:42.064613Z",
"updated_at": "2023-06-14T17:05:42.064979Z",
"exercise": 370,
"muscle": 4
},
{
"id": 9147,
"created_at": "2023-06-14T17:05:42.065611Z",
"updated_at": "2023-06-14T17:05:42.066018Z",
"exercise": 370,
"muscle": 6 "muscle": 6
}, },
{ {
"id": 9148, "id": 7271,
"created_at": "2023-06-14T17:05:42.066724Z", "created_at": "2023-06-14T17:05:39.770480Z",
"updated_at": "2023-06-14T17:05:42.067255Z", "updated_at": "2023-06-14T17:05:39.771111Z",
"exercise": 370, "exercise": 992,
"muscle": 3 "muscle": 4
} }
], ],
"equipment": [ "equipment": [
{ {
"id": 1763, "id": 944,
"created_at": "2023-06-13T02:28:05.215315Z", "created_at": "2023-06-13T02:28:04.294180Z",
"updated_at": "2023-06-13T02:28:05.215849Z", "updated_at": "2023-06-13T02:28:04.294658Z",
"exercise": 370, "exercise": 992,
"equipment": 1091 "equipment": 1091
} }
], ],
"audio_url": "/media/exercise_audio/Single-Arm_Dumbbell_Suitcase_Deadlift.m4a", "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a",
"video_url": "/media/exercise_videos/Single-Arm_Dumbbell_Suitcase_Deadlift.mp4", "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4",
"created_at": "2023-06-11T22:50:18.961690Z", "created_at": "2023-06-11T22:50:19.197099Z",
"updated_at": "2023-06-11T22:50:18.961696Z", "updated_at": "2023-06-11T22:50:19.197105Z",
"name": "Single-Arm Dumbbell Suitcase Deadlift", "name": "2 Dumbbell Single-Leg Deadlift",
"description": "Start with your feet just outside your hips,, and the dumbbell in your right hand.. Hinge your hips back,, and let your shoulders forward to lower the weight.. Push through the ground to stand up..", "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.",
"side": "right_arm", "side": "right_leg",
"is_two_dumbbells": false, "is_two_dumbbells": true,
"is_trackable_distance": false, "is_trackable_distance": false,
"is_alternating": false, "is_alternating": false,
"is_weight": true, "is_weight": true,
"is_distance": false, "is_distance": false,
"is_duration": true, "is_duration": true,
"is_reps": true, "is_reps": true,
"joints_used": "ankle,lumbar spine,elbow,hip,knee", "joints_used": "ankle,lumbar spine,hip,knee,wrist",
"movement_patterns": "lower pull,lower pull - hip hinge", "movement_patterns": "lower pull,lower pull - hip hinge",
"equipment_required": "Dumbbell", "equipment_required": "Dumbbell",
"muscle_groups": "glutes,hamstrings,obliques", "muscle_groups": "hamstrings,glutes",
"synonyms": "Single Arm Dumbbell Suitcase Deadlift" "synonyms": "2 Dumbbell Single Leg Deadlift"
}, },
"weight": 30, "weight": 10,
"reps": null, "reps": 12,
"duration": 35, "duration": null,
"duration_audio": "/media/quantities_audio/for_35_seconds.m4a", "duration_audio": null,
"weight_audio": "/media/quantities_audio/for_30_pounds.m4a", "weight_audio": "/media/quantities_audio/for_10_pounds.m4a",
"created_at": "2023-06-14T13:28:52.947298Z" "created_at": "2023-06-20T20:53:51.251968Z"
}, },
{ {
"workout": 4, "workout": 20,
"exercise": { "exercise": {
"id": 1012, "id": 992,
"muscles": [ "muscles": [
{ {
"id": 8968, "id": 7270,
"created_at": "2023-06-14T17:05:41.850461Z", "created_at": "2023-06-14T17:05:39.769351Z",
"updated_at": "2023-06-14T17:05:41.850890Z", "updated_at": "2023-06-14T17:05:39.769758Z",
"exercise": 1012, "exercise": 992,
"muscle": 2 "muscle": 6
}, },
{ {
"id": 8969, "id": 7271,
"created_at": "2023-06-14T17:05:41.851562Z", "created_at": "2023-06-14T17:05:39.770480Z",
"updated_at": "2023-06-14T17:05:41.851932Z", "updated_at": "2023-06-14T17:05:39.771111Z",
"exercise": 1012, "exercise": 992,
"muscle": 27
}
],
"equipment": [
{
"id": 1675,
"created_at": "2023-06-13T02:28:05.120220Z",
"updated_at": "2023-06-13T02:28:05.120555Z",
"exercise": 1012,
"equipment": 1089
}
],
"audio_url": "/media/exercise_audio/Scissors.m4a",
"video_url": "/media/exercise_videos/Scissors.mp4",
"created_at": "2023-06-11T22:50:19.204261Z",
"updated_at": "2023-06-11T22:50:19.204267Z",
"name": "Scissors",
"description": "",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": true,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": true,
"joints_used": "lumbar spine,hip",
"movement_patterns": "core",
"equipment_required": "Yoga Mat",
"muscle_groups": "core,hip adductors",
"synonyms": ""
},
"weight": null,
"reps": null,
"duration": 35,
"duration_audio": "/media/quantities_audio/for_35_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.947467Z"
},
{
"workout": 4,
"exercise": {
"id": 798,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 20,
"duration_audio": "/media/quantities_audio/for_20_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.947631Z"
},
{
"workout": 4,
"exercise": {
"id": 495,
"muscles": [
{
"id": 7696,
"created_at": "2023-06-14T17:05:40.301365Z",
"updated_at": "2023-06-14T17:05:40.301765Z",
"exercise": 495,
"muscle": 4 "muscle": 4
},
{
"id": 7697,
"created_at": "2023-06-14T17:05:40.302477Z",
"updated_at": "2023-06-14T17:05:40.302855Z",
"exercise": 495,
"muscle": 5
} }
], ],
"equipment": [ "equipment": [
{ {
"id": 1139, "id": 944,
"created_at": "2023-06-13T02:28:04.524659Z", "created_at": "2023-06-13T02:28:04.294180Z",
"updated_at": "2023-06-13T02:28:04.525069Z", "updated_at": "2023-06-13T02:28:04.294658Z",
"exercise": 495, "exercise": 992,
"equipment": 1089 "equipment": 1091
} }
], ],
"audio_url": "/media/exercise_audio/Chair_Pose.m4a", "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a",
"video_url": "/media/exercise_videos/Chair_Pose.mp4", "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4",
"created_at": "2023-06-11T22:50:19.010855Z", "created_at": "2023-06-11T22:50:19.197099Z",
"updated_at": "2023-06-11T22:50:19.010862Z", "updated_at": "2023-06-11T22:50:19.197105Z",
"name": "Chair Pose", "name": "2 Dumbbell Single-Leg Deadlift",
"description": "", "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.",
"side": "", "side": "right_leg",
"is_two_dumbbells": false, "is_two_dumbbells": true,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "ankle,hip,knee,shoulder",
"movement_patterns": "yoga",
"equipment_required": "Yoga Mat",
"muscle_groups": "glutes,quads",
"synonyms": ""
},
"weight": null,
"reps": null,
"duration": 30,
"duration_audio": "/media/quantities_audio/for_30_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.947793Z"
},
{
"workout": 4,
"exercise": {
"id": 798,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 10,
"duration_audio": "/media/quantities_audio/for_10_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.947967Z"
},
{
"workout": 4,
"exercise": {
"id": 448,
"muscles": [
{
"id": 9651,
"created_at": "2023-06-14T17:05:42.656915Z",
"updated_at": "2023-06-14T17:05:42.657363Z",
"exercise": 448,
"muscle": 9
},
{
"id": 9652,
"created_at": "2023-06-14T17:05:42.658005Z",
"updated_at": "2023-06-14T17:05:42.658465Z",
"exercise": 448,
"muscle": 15
}
],
"equipment": [
{
"id": 1971,
"created_at": "2023-06-13T02:28:05.459371Z",
"updated_at": "2023-06-13T02:28:05.459787Z",
"exercise": 448,
"equipment": 1106
}
],
"audio_url": "/media/exercise_audio/Wall_Slide_with_Lift_Off.m4a",
"video_url": "/media/exercise_videos/Wall_Slide_with_Lift_Off.mp4",
"created_at": "2023-06-11T22:50:18.992528Z",
"updated_at": "2023-06-11T22:50:18.992535Z",
"name": "Wall Slide with Lift Off",
"description": "Face a wall with the base of your hand touching the wall and palms facing each other. Slide your hands up the wall while maintaining the same back and forearm position. At the top of the movement, lift your hands off the wall. Replace your hands back on the wall before sliding back down.",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false, "is_trackable_distance": false,
"is_alternating": false, "is_alternating": false,
"is_weight": true, "is_weight": true,
"is_distance": false, "is_distance": false,
"is_duration": true, "is_duration": true,
"is_reps": true, "is_reps": true,
"joints_used": "shoulder,elbow", "joints_used": "ankle,lumbar spine,hip,knee,wrist",
"movement_patterns": "mobility,mobility - dynamic", "movement_patterns": "lower pull,lower pull - hip hinge",
"equipment_required": "Wall", "equipment_required": "Dumbbell",
"muscle_groups": "upper back,rotator cuff", "muscle_groups": "hamstrings,glutes",
"synonyms": "" "synonyms": "2 Dumbbell Single Leg Deadlift"
}, },
"weight": null, "weight": 10,
"reps": null, "reps": 12,
"duration": 30, "duration": null,
"duration_audio": "/media/quantities_audio/for_30_seconds.m4a", "duration_audio": null,
"weight_audio": null, "weight_audio": "/media/quantities_audio/for_10_pounds.m4a",
"created_at": "2023-06-14T13:28:52.948128Z" "created_at": "2023-06-20T20:53:51.254113Z"
}, },
{ {
"workout": 4, "workout": 20,
"exercise": { "exercise": {
"id": 798, "id": 992,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 10,
"duration_audio": "/media/quantities_audio/for_10_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.948291Z"
},
{
"workout": 4,
"exercise": {
"id": 1045,
"muscles": [ "muscles": [
{ {
"id": 7741, "id": 7270,
"created_at": "2023-06-14T17:05:40.358740Z", "created_at": "2023-06-14T17:05:39.769351Z",
"updated_at": "2023-06-14T17:05:40.359220Z", "updated_at": "2023-06-14T17:05:39.769758Z",
"exercise": 1045, "exercise": 992,
"muscle": 6
},
{
"id": 7271,
"created_at": "2023-06-14T17:05:39.770480Z",
"updated_at": "2023-06-14T17:05:39.771111Z",
"exercise": 992,
"muscle": 4 "muscle": 4
},
{
"id": 7742,
"created_at": "2023-06-14T17:05:40.360107Z",
"updated_at": "2023-06-14T17:05:40.360946Z",
"exercise": 1045,
"muscle": 5
},
{
"id": 7743,
"created_at": "2023-06-14T17:05:40.362207Z",
"updated_at": "2023-06-14T17:05:40.363132Z",
"exercise": 1045,
"muscle": 16
} }
], ],
"equipment": [ "equipment": [
{ {
"id": 1149, "id": 944,
"created_at": "2023-06-13T02:28:04.535504Z", "created_at": "2023-06-13T02:28:04.294180Z",
"updated_at": "2023-06-13T02:28:04.535969Z", "updated_at": "2023-06-13T02:28:04.294658Z",
"exercise": 1045, "exercise": 992,
"equipment": 1089 "equipment": 1091
} }
], ],
"audio_url": "/media/exercise_audio/Crescent_Lunge.m4a", "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a",
"video_url": "/media/exercise_videos/Crescent_Lunge.mp4", "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4",
"created_at": "2023-06-11T22:50:19.216136Z", "created_at": "2023-06-11T22:50:19.197099Z",
"updated_at": "2023-06-11T22:50:19.216142Z", "updated_at": "2023-06-11T22:50:19.197105Z",
"name": "Crescent Lunge", "name": "2 Dumbbell Single-Leg Deadlift",
"description": "", "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.",
"side": "left_side", "side": "right_leg",
"is_two_dumbbells": false, "is_two_dumbbells": true,
"is_trackable_distance": false, "is_trackable_distance": false,
"is_alternating": false, "is_alternating": false,
"is_weight": false, "is_weight": true,
"is_distance": false, "is_distance": false,
"is_duration": true, "is_duration": true,
"is_reps": false, "is_reps": true,
"joints_used": "ankle,hip,knee,shoulder", "joints_used": "ankle,lumbar spine,hip,knee,wrist",
"movement_patterns": "yoga,mobility - static,lower push - lunge", "movement_patterns": "lower pull,lower pull - hip hinge",
"equipment_required": "Yoga Mat", "equipment_required": "Dumbbell",
"muscle_groups": "glutes,quads,hip flexor", "muscle_groups": "hamstrings,glutes",
"synonyms": "" "synonyms": "2 Dumbbell Single Leg Deadlift"
}, },
"weight": null, "weight": 10,
"reps": null, "reps": 12,
"duration": 30, "duration": null,
"duration_audio": "/media/quantities_audio/for_30_seconds.m4a", "duration_audio": null,
"weight_audio": null, "weight_audio": "/media/quantities_audio/for_10_pounds.m4a",
"created_at": "2023-06-14T13:28:52.948449Z" "created_at": "2023-06-20T20:53:51.255969Z"
},
{
"workout": 4,
"exercise": {
"id": 1047,
"muscles": [
{
"id": 7744,
"created_at": "2023-06-14T17:05:40.364417Z",
"updated_at": "2023-06-14T17:05:40.364979Z",
"exercise": 1047,
"muscle": 4
},
{
"id": 7745,
"created_at": "2023-06-14T17:05:40.365773Z",
"updated_at": "2023-06-14T17:05:40.366233Z",
"exercise": 1047,
"muscle": 5
},
{
"id": 7746,
"created_at": "2023-06-14T17:05:40.366905Z",
"updated_at": "2023-06-14T17:05:40.367271Z",
"exercise": 1047,
"muscle": 16
}
],
"equipment": [
{
"id": 1150,
"created_at": "2023-06-13T02:28:04.536605Z",
"updated_at": "2023-06-13T02:28:04.537010Z",
"exercise": 1047,
"equipment": 1089
}
],
"audio_url": "/media/exercise_audio/Crescent_Lunge.m4a",
"video_url": "/media/exercise_videos/Crescent_Lunge.mp4",
"created_at": "2023-06-11T22:50:19.216834Z",
"updated_at": "2023-06-11T22:50:19.216840Z",
"name": "Crescent Lunge",
"description": "",
"side": "right_side",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "ankle,hip,knee,shoulder",
"movement_patterns": "yoga,mobility - static,lower push - lunge",
"equipment_required": "Yoga Mat",
"muscle_groups": "glutes,quads,hip flexor",
"synonyms": ""
},
"weight": null,
"reps": null,
"duration": 30,
"duration_audio": "/media/quantities_audio/for_30_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.948594Z"
},
{
"workout": 4,
"exercise": {
"id": 798,
"muscles": [],
"equipment": [],
"audio_url": "/media/exercise_audio/Recover.m4a",
"video_url": "/media/exercise_videos/Recover.mp4",
"created_at": "2023-06-11T22:50:19.127914Z",
"updated_at": "2023-06-11T22:50:19.127921Z",
"name": "Recover",
"description": "Use this time to catch your breath. It will help you get more out of what's next",
"side": "",
"is_two_dumbbells": false,
"is_trackable_distance": false,
"is_alternating": false,
"is_weight": false,
"is_distance": false,
"is_duration": true,
"is_reps": false,
"joints_used": "",
"movement_patterns": "",
"equipment_required": "",
"muscle_groups": "",
"synonyms": null
},
"weight": null,
"reps": null,
"duration": 10,
"duration_audio": "/media/quantities_audio/for_10_seconds.m4a",
"weight_audio": null,
"created_at": "2023-06-14T13:28:52.948713Z"
} }
], ],
"registered_user": { "registered_user": {
"id": 1, "id": 2,
"first_name": "test1_fist", "first_name": "test2_first",
"last_name": "test1_last", "last_name": "test2_last",
"image": "", "image": "",
"nick_name": null "nick_name": null
} }

View File

@@ -36,8 +36,14 @@ class AllExerciseFetchable: Fetchable {
var endPoint: String = "exercise/all/" var endPoint: String = "exercise/all/"
} }
class CompletedWorkoutFetchable: Fetchable {
typealias Response = [CompletedWorkout]
var endPoint: String = "workout/completed/"
}
class CreateWorkoutFetchable: Postable { class CreateWorkoutFetchable: Postable {
var postableData: [String : Any]? var postableData: [String : Any]?
var successStatus = 201
typealias Response = Workout typealias Response = Workout
var endPoint: String = "workout/create/" var endPoint: String = "workout/create/"
@@ -49,6 +55,7 @@ class CreateWorkoutFetchable: Postable {
class CompleteWorkoutFetchable: Postable { class CompleteWorkoutFetchable: Postable {
var postableData: [String : Any]? var postableData: [String : Any]?
var successStatus = 201
typealias Response = CompletedWorkout typealias Response = CompletedWorkout
var endPoint: String = "workout/complete/" var endPoint: String = "workout/complete/"
@@ -57,3 +64,19 @@ class CompleteWorkoutFetchable: Postable {
self.postableData = postData self.postableData = postData
} }
} }
class LoginFetchable: Postable {
var postableData: [String : Any]?
var successStatus = 200
typealias Response = RegisteredUser
var endPoint: String = "registered_user/login/"
var attachToken: Bool {
return false
}
init(postData: [String: Any]) {
self.postableData = postData
}
}

View File

@@ -13,12 +13,13 @@ enum FetchableError: Error {
case decodeError(Error) case decodeError(Error)
case endOfFileError case endOfFileError
case noPostData case noPostData
case noToken
case statusError(Int, String?) case statusError(Int, String?)
} }
protocol Fetchable { protocol Fetchable {
associatedtype Response: Codable associatedtype Response: Codable
var attachToken: Bool { get }
var baseURL: String { get } var baseURL: String { get }
var endPoint: String { get } var endPoint: String { get }
func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void)
@@ -26,6 +27,7 @@ protocol Fetchable {
protocol Postable: Fetchable { protocol Postable: Fetchable {
var postableData: [String: Any]? { get } var postableData: [String: Any]? { get }
var successStatus: Int { get }
} }
extension Fetchable { extension Fetchable {
@@ -33,10 +35,24 @@ extension Fetchable {
"http://127.0.0.1:8000/" "http://127.0.0.1:8000/"
} }
var attachToken: Bool {
return true
}
func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) { func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) {
let url = URL(string: baseURL+endPoint)! let url = URL(string: baseURL+endPoint)!
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in var request = URLRequest(url: url,timeoutInterval: Double.infinity)
if attachToken {
guard let token = UserStore.shared.token else {
completion(.failure(.noPostData))
return
}
request.addValue(token, forHTTPHeaderField: "Authorization")
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
if let error = error { if let error = error {
completion(.failure(.apiError(error))) completion(.failure(.apiError(error)))
return return
@@ -62,17 +78,23 @@ extension Fetchable {
extension Postable { extension Postable {
func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) { func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) {
guard let postableData = postableData else { guard let postableData = postableData else {
completion(.failure(.noPostData)) completion(.failure(.noPostData))
return return
} }
let url = URL(string: baseURL+endPoint)! let url = URL(string: baseURL+endPoint)!
let postData = try! JSONSerialization.data(withJSONObject:postableData) let postData = try! JSONSerialization.data(withJSONObject:postableData)
var request = URLRequest(url: url,timeoutInterval: Double.infinity) var request = URLRequest(url: url,timeoutInterval: Double.infinity)
request.addValue("Token fd59cbf6f5db98726e896cdb6b095ecb9c43a592", forHTTPHeaderField: "Authorization") if attachToken {
guard let token = UserStore.shared.token else {
completion(.failure(.noPostData))
return
}
request.addValue(token, forHTTPHeaderField: "Authorization")
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST" request.httpMethod = "POST"
@@ -85,7 +107,7 @@ extension Postable {
} }
if let httpRespone = response as? HTTPURLResponse { if let httpRespone = response as? HTTPURLResponse {
if httpRespone.statusCode != 201 { if httpRespone.statusCode != successStatus {
var returnStr: String? var returnStr: String?
if let data = data { if let data = data {
returnStr = String(data: data, encoding: .utf8) returnStr = String(data: data, encoding: .utf8)

View File

@@ -74,4 +74,34 @@ class PreviewWorkout {
fatalError() fatalError()
} }
} }
class func parseRegisterdUser() -> RegisteredUser {
if let filepath = Bundle.main.path(forResource: "RegisteredUser", ofType: "json") {
do {
let data = try Data(NSData(contentsOfFile: filepath))
let muscles = try JSONDecoder().decode(RegisteredUser.self, from: data)
return muscles
} catch {
print(error)
fatalError()
}
} else {
fatalError()
}
}
class func parseCompletedWorkouts() -> [CompletedWorkout] {
if let filepath = Bundle.main.path(forResource: "CompletedWorkouts", ofType: "json") {
do {
let data = try Data(NSData(contentsOfFile: filepath))
let muscles = try JSONDecoder().decode([CompletedWorkout].self, from: data)
return muscles
} catch {
print(error)
fatalError()
}
} else {
fatalError()
}
}
} }

View File

@@ -0,0 +1,38 @@
//
// UserStore.swift
// Werkout_ios
//
// Created by Trey Tartt on 6/25/23.
//
import Foundation
class UserStore: ObservableObject {
static let shared = UserStore()
@Published public private(set) var registeredUser: RegisteredUser?
public var token: String? {
guard let token = registeredUser?.token else {
return nil
}
return "Token \(token)"
}
func login(completion: @escaping (Bool)-> Void) {
let postData = ["email": "user1@user1.com", "password":"test12345"]
LoginFetchable(postData: postData).fetch(completion: { result in
switch result {
case .success(let model):
self.registeredUser = model
completion(true)
case .failure(let failure):
completion(false)
}
})
}
func setFakeUser() {
self.registeredUser = PreviewWorkout.parseRegisterdUser()
}
}

View File

@@ -46,14 +46,22 @@ struct AllWorkoutsView: View {
} }
}.onAppear{ }.onAppear{
if needsUpdating { if needsUpdating {
AllWorkoutFetchable().fetch(completion: { result in UserStore.shared.login(completion: { success in
needsUpdating = false if success {
switch result { DataStore.shared.fetchAllData()
case .success(let model):
DispatchQueue.main.async { AllWorkoutFetchable().fetch(completion: { result in
self.workouts = model needsUpdating = false
} switch result {
case .failure(let failure): case .success(let model):
DispatchQueue.main.async {
self.workouts = model
}
case .failure(let failure):
fatalError("shit broke")
}
})
} else {
fatalError("shit broke") fatalError("shit broke")
} }
}) })

View File

@@ -21,15 +21,28 @@ struct CompletedWorkoutView: View {
VStack { VStack {
topViews() topViews()
calsBurned() Divider()
heartRates() HStack {
calsBurned()
.frame(maxWidth: .infinity)
heartRates()
.frame(maxWidth: .infinity)
}
rateWorkout() rateWorkout()
.frame(maxHeight: 88)
Divider() Divider()
TextField("Notes", text: $notes) TextField("Notes", text: $notes)
.frame(height: 55)
.textFieldStyle(PlainTextFieldStyle())
.padding([.horizontal], 4)
.overlay(RoundedRectangle(cornerRadius: 16).stroke(Color(uiColor: .clear))).background(Color(uiColor: .init(red: 200/255, green: 200/255, blue: 200/255, alpha: 0.2)))
.cornerRadius(8)
Spacer() Spacer()
@@ -66,9 +79,16 @@ struct CompletedWorkoutView: View {
func calsBurned() -> some View { func calsBurned() -> some View {
VStack { VStack {
Divider() if let cals = postData["total_calories"] as? Float {
Text("calroies burned") HStack {
Text("\(postData["total_calories"] as! Float)") Image(systemName: "flame.fill")
.foregroundColor(.orange)
.font(.title)
VStack {
Text("\(cals, specifier: "%.0f")")
}
}
}
} }
} }
@@ -76,24 +96,47 @@ struct CompletedWorkoutView: View {
VStack { VStack {
Divider() Divider()
Text("how hard was this shit")
HStack { HStack {
Text("easy") Text("Easy")
.foregroundColor(.green)
Spacer() Spacer()
Text("Death") Text("Death")
.foregroundColor(.red)
} }
Slider(value: $difficulty, in: 0...5, step: 1) ZStack {
LinearGradient(
gradient: Gradient(colors: [.green, .red]),
startPoint: .leading,
endPoint: .trailing
)
.mask(Slider(value: $difficulty, in: 0...5, step: 1))
// Dummy replicated slider, to allow sliding
Slider(value: $difficulty, in: 0...5, step: 1)
.opacity(0.05) // Opacity is the trick here.
.accentColor(.clear)
}
} }
} }
func heartRates() -> some View { func heartRates() -> some View {
VStack { VStack {
Divider()
if let heartRates = postData["heart_rates"] as? [Int] { if let heartRates = postData["heart_rates"] as? [Int] {
let avg = heartRates.reduce(0, +)/heartRates.count let avg = heartRates.reduce(0, +)/heartRates.count
Text("Avg heart rate: \(avg)") HStack {
Image(systemName: "heart")
.foregroundColor(.red)
.font(.title)
VStack {
HStack {
Text("\(heartRates.min() ?? 0)")
Text("-")
Text("\(heartRates.max() ?? 0)")
}
Text("\(avg)")
}
}
} }
} }
} }
@@ -119,17 +162,21 @@ struct CompletedWorkoutView: View {
} }
} }
//struct CompletedWorkoutView_Previews: PreviewProvider { struct CompletedWorkoutView_Previews: PreviewProvider {
// static let postBody = [ static let postBody = [
// "difficulty": 1, "difficulty": 1,
// "workout_start_time": Date().timeFormatForUpload, "workout_start_time": Date().timeFormatForUpload,
// "workout": 1, "workout": 1,
// "total_time": 140 "total_time": 140,
// ] as [String : Any] "total_calories": Float(120.0),
// "heart_rates": [65,65,4,54,232,12]
// static let workout = PreviewWorkout.workout() ] as [String : Any]
//
// static var previews: some View { static let workout = PreviewWorkout.workout()
// CompletedWorkoutView(postData: CompletedWorkoutView_Previews.postBody, workout: workout)
// } static var previews: some View {
//} CompletedWorkoutView(postData: CompletedWorkoutView_Previews.postBody,
workout: workout,
completedWorkoutDismissed: { _ in })
}
}

View File

@@ -62,7 +62,7 @@ struct Werkout_iosApp: App {
.tag(3) .tag(3)
} }
.onAppear{ .onAppear{
DataStore.shared.fetchAllData()
} }
.onReceive(pub) { (output) in .onReceive(pub) { (output) in
self.tabSelection = 1 self.tabSelection = 1