import SwiftUI import SwiftData struct ActiveWorkoutSession: View { @Environment(\.modelContext) private var modelContext @Default(\.isWorkingOut) var isWorkingOut @Query(sort: \WorkoutSession.name) private var workoutSessions: [WorkoutSession] @State private var activeWorkoutSession: WorkoutSession? @Default(\.activeWorkoutSessionId) var activeWorkoutSessionId @Query(sort: \Workout.name) private var workouts: [Workout] @State private var activeWorkout: Workout? @Default(\.activeWorkoutId) var activeWorkoutId var body: some View { VStack { List { Section(footer: Text(activeWorkoutSession?.creationDate.ISO8601Format() ?? "Unknown Date")) { NavigationLink(destination: { ItemPicker(items: workouts, selectedItem: $activeWorkout) }) { Text(activeWorkout?.name ?? "Select your next Workout") } .onChange(of: activeWorkout) { _, newWorkout in if let workout = newWorkout { activeWorkoutId = workout.id.uuidString activeWorkoutSession?.workout = workout } } } if let activeWorkout = activeWorkout { Section(header: Text("Exercises")) { ForEach(activeWorkout.workoutItems.sorted(by: { $0.position < $1.position })) { workoutItem in HStack { Text(String(workoutItem.reps)) Text(workoutItem.name) Spacer() Button(action: { // TODO: Implement a sheet view; don't use ExerciseDetail since its purpose is editing }) { Image(systemName: "info.circle") .foregroundColor(.blue) } } } } } } if true { // This condition should be more meaningful. VStack { HStack { Text(String(workoutSessions.count)) Button(action: { // save(workoutSession: activeWorkoutSession) }) { Text("Save Session") } .buttonStyle(.borderedProminent) } } } // MARK: -- Workout Controls Group { if activeWorkoutSession?.workout != nil { if isWorkingOut { // MARK: -- Stop Workout VStack { ProgressView("", value: 10, total: 100) TimerView(isActive: $isWorkingOut) .font(.title) .bold() Button(action: { isWorkingOut = false activeWorkoutSession?.startWorkoutSession() }) { HStack { Image(systemName: "stop.fill") Text("Stop Workout") } } .buttonStyle(.borderedProminent) .bold() .tint(.red) } } else { // MARK: -- Start Workout Button(action: { isWorkingOut = true activeWorkoutSession?.stopWorkoutSession() }) { HStack { Image(systemName: "play.fill") Text("Start Workout") } } .buttonStyle(.borderedProminent) .bold() .tint(.green) } } } } .navigationTitle("Workout Session") .onAppear { // Load the active workout session and workout onAppear if let activeWorkoutSession = getItem(from: workoutSessions, by: activeWorkoutSessionId) { self.activeWorkoutSession = activeWorkoutSession if let workout = getItem(from: workouts, by: activeWorkoutId) { self.activeWorkout = workout } } else { createNewWorkoutSession() } } } private func createNewWorkoutSession() { let newWorkoutSession = WorkoutSession() activeWorkoutSessionId = newWorkoutSession.id.uuidString if let selectedWorkout = getItem(from: workouts, by: activeWorkoutId) { newWorkoutSession.workout = selectedWorkout } self.activeWorkoutSession = newWorkoutSession } private func getItem(from array: [Item], by id: String) -> Item? { let filteredItems = array.filter { $0.id == UUID(uuidString: id) } return filteredItems.count == 1 ? filteredItems.first : nil } } #Preview { NavigationStack { ActiveWorkoutSession() } .modelContainer(SampleData.shared.modelContainer) } #Preview("No Workout Selected") { NavigationStack { ActiveWorkoutSession() } .onAppear { Defaults.shared.isWorkingOut = false } .modelContainer(SampleData.shared.modelContainer) } #Preview("No Workout Data available") { NavigationStack { ActiveWorkoutSession() } }