import SwiftUI struct ActiveWorkoutView: View { @ObservedObject var workoutManager: WorkoutManager var body: some View { TabView { if workoutManager.isResting { RestPage(workoutManager: workoutManager) } else { ActivePage(workoutManager: workoutManager) } WorkoutOverviewPage(workoutManager: workoutManager) ControlsPage(workoutManager: workoutManager) } .tabViewStyle(.verticalPage) } } // MARK: - Page 1: Active / Rest struct ActivePage: View { @ObservedObject var workoutManager: WorkoutManager var body: some View { VStack(spacing: 6) { if let workout = workoutManager.selectedWorkout, workoutManager.currentSetIndex < workout.sets.count { let currentSet = workout.sets[workoutManager.currentSetIndex] HStack { Text("Set \(workoutManager.currentSetIndex + 1)/\(workout.sets.count)") .font(.caption2) .foregroundColor(.secondary) Text("ยท") .foregroundColor(.secondary) Text("Rep \(workoutManager.currentRep + 1)/\(currentSet.repCount)") .font(.caption2) .foregroundColor(.secondary) } Text(currentSet.stroke) .font(.headline) .foregroundColor(.cyan) Text("\(Int(workoutManager.currentSetDistanceSwum))/\(Int(workoutManager.currentSetTotalDistance))m") .font(.system(size: 36, weight: .bold, design: .rounded)) .foregroundColor(.cyan) } HStack(spacing: 4) { Image(systemName: "figure.pool.swim") .font(.caption) .foregroundColor(.cyan) Text("\(Int(workoutManager.totalDistanceSwum))m total") .font(.caption) .foregroundColor(.secondary) } Text(formatTime(workoutManager.elapsedSeconds)) .font(.system(.title3, design: .monospaced)) HStack(spacing: 12) { HStack(spacing: 4) { Image(systemName: "flame.fill") .foregroundColor(.orange) .font(.caption) Text("\(Int(workoutManager.activeCalories))") .font(.caption) } if workoutManager.heartRate > 0 { HStack(spacing: 4) { Image(systemName: "heart.fill") .foregroundColor(.red) .font(.caption) Text("\(Int(workoutManager.heartRate))") .font(.caption) } } } if workoutManager.lapDetected { Text("Lap detected!") .font(.caption) .foregroundColor(.green) .transition(.opacity) } } } private func formatTime(_ seconds: TimeInterval) -> String { let mins = Int(seconds) / 60 let secs = Int(seconds) % 60 return String(format: "%d:%02d", mins, secs) } } struct RestPage: View { @ObservedObject var workoutManager: WorkoutManager var body: some View { VStack(spacing: 12) { Text("Rest") .font(.headline) .foregroundColor(.secondary) Text(formatTime(workoutManager.restTimeRemaining)) .font(.system(size: 44, weight: .bold, design: .monospaced)) .foregroundColor(.cyan) if let workout = workoutManager.selectedWorkout, workoutManager.currentSetIndex + 1 < workout.sets.count { let nextSet = workout.sets[workoutManager.currentSetIndex + 1] Text("Next: \(nextSet.stroke) \(nextSet.distancePerRep)m") .font(.caption) .foregroundColor(.secondary) } HStack(spacing: 12) { HStack(spacing: 4) { Image(systemName: "figure.pool.swim") .font(.caption) .foregroundColor(.cyan) Text("\(Int(workoutManager.totalDistanceSwum))m") .font(.caption) } HStack(spacing: 4) { Image(systemName: "flame.fill") .foregroundColor(.orange) .font(.caption) Text("\(Int(workoutManager.activeCalories))kcal") .font(.caption) } } .foregroundColor(.secondary) } } private func formatTime(_ seconds: TimeInterval) -> String { let mins = Int(seconds) / 60 let secs = Int(seconds) % 60 return String(format: "%d:%02d", mins, secs) } } // MARK: - Page 2: Workout Overview struct WorkoutOverviewPage: View { @ObservedObject var workoutManager: WorkoutManager var body: some View { ScrollView { VStack(alignment: .leading, spacing: 6) { if workoutManager.isResting { HStack { Image(systemName: "pause.circle.fill") .foregroundColor(.orange) .font(.caption) Text("Rest \(formatTime(workoutManager.restTimeRemaining))") .font(.caption) .foregroundColor(.orange) } } if let workout = workoutManager.selectedWorkout { ForEach(Array(workout.sets.enumerated()), id: \.offset) { i, set in HStack { Circle() .fill(i < workoutManager.currentSetIndex ? .green : i == workoutManager.currentSetIndex ? .cyan : .gray.opacity(0.4)) .frame(width: 8, height: 8) Text("\(i + 1). \(set.stroke)") .font(.caption) .foregroundColor(i <= workoutManager.currentSetIndex ? .primary : .secondary) Spacer() Text("\(set.repCount)x\(set.distancePerRep)m") .font(.caption2) .foregroundColor(.secondary) } } } } .padding(.top, 4) } } private func formatTime(_ seconds: TimeInterval) -> String { let mins = Int(seconds) / 60 let secs = Int(seconds) % 60 return String(format: "%d:%02d", mins, secs) } } // MARK: - Page 3: Controls struct ControlsPage: View { @ObservedObject var workoutManager: WorkoutManager var body: some View { VStack(spacing: 16) { if workoutManager.isWaterLockEnabled { HStack(spacing: 4) { Image(systemName: "drop.fill") .foregroundColor(.cyan) .font(.caption) Text("Water Lock") .font(.caption) .foregroundColor(.cyan) } } Spacer() Button { if workoutManager.isPaused { workoutManager.resumeWorkout() } else { workoutManager.pauseWorkout() } } label: { VStack(spacing: 4) { Image(systemName: workoutManager.isPaused ? "play.fill" : "pause.fill") .font(.title2) Text(workoutManager.isPaused ? "Resume" : "Pause") .font(.caption) } .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) .tint(.orange) Button { workoutManager.endWorkout() } label: { VStack(spacing: 4) { Image(systemName: "stop.fill") .font(.title2) Text("End Workout") .font(.caption) } .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) .tint(.red) Spacer() } } }