// // WorkoutLogsView.swift // Workouts // // Created by rzen on 7/13/25 at 6:52 PM. // // Copyright 2025 Rouslan Zenetl. All Rights Reserved. // import SwiftUI import CoreData struct WorkoutLogsView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Workout.start, ascending: false)], animation: .default ) private var workouts: FetchedResults @State private var showingSplitPicker = false @State private var itemToDelete: Workout? = nil var body: some View { NavigationStack { List { ForEach(workouts, id: \.objectID) { workout in NavigationLink(destination: WorkoutLogListView(workout: workout)) { CalendarListItem( date: workout.start, title: workout.split?.name ?? Split.unnamed, subtitle: getSubtitle(for: workout), subtitle2: workout.statusName ) } .swipeActions(edge: .trailing, allowsFullSwipe: false) { Button { itemToDelete = workout } label: { Label("Delete", systemImage: "trash") } .tint(.red) } } } .overlay { if workouts.isEmpty { ContentUnavailableView( "No Workouts Yet", systemImage: "list.bullet.clipboard", description: Text("Start a new workout from one of your splits.") ) } } .navigationTitle("Workout Logs") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Start New") { showingSplitPicker.toggle() } } } .sheet(isPresented: $showingSplitPicker) { SplitPickerSheet() } .confirmationDialog( "Delete Workout?", isPresented: Binding( get: { itemToDelete != nil }, set: { if !$0 { itemToDelete = nil } } ), titleVisibility: .visible ) { Button("Delete", role: .destructive) { if let item = itemToDelete { withAnimation { viewContext.delete(item) try? viewContext.save() itemToDelete = nil } } } Button("Cancel", role: .cancel) { itemToDelete = nil } } } } private func getSubtitle(for workout: Workout) -> String { if workout.status == .completed, let endDate = workout.end { return workout.start.humanTimeInterval(to: endDate) } else { return workout.start.formattedDate() } } } // MARK: - Split Picker Sheet struct SplitPickerSheet: View { @Environment(\.managedObjectContext) private var viewContext @Environment(\.dismiss) private var dismiss @FetchRequest( sortDescriptors: [ NSSortDescriptor(keyPath: \Split.order, ascending: true), NSSortDescriptor(keyPath: \Split.name, ascending: true) ], animation: .default ) private var splits: FetchedResults var body: some View { NavigationStack { List { ForEach(splits, id: \.objectID) { split in Button { startWorkout(with: split) } label: { HStack { Image(systemName: split.systemImage) .foregroundColor(Color.color(from: split.color)) Text(split.name) Spacer() Text("\(split.exercisesArray.count) exercises") .font(.caption) .foregroundColor(.secondary) } } } } .navigationTitle("Select a Split") .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { dismiss() } } } } } private func startWorkout(with split: Split) { let workout = Workout(context: viewContext) workout.start = Date() workout.status = .notStarted workout.split = split for exercise in split.exercisesArray { let workoutLog = WorkoutLog(context: viewContext) workoutLog.exerciseName = exercise.name workoutLog.date = Date() workoutLog.order = exercise.order workoutLog.sets = exercise.sets workoutLog.reps = exercise.reps workoutLog.weight = exercise.weight workoutLog.status = .notStarted workoutLog.workout = workout } try? viewContext.save() dismiss() } } #Preview { WorkoutLogsView() .environment(\.managedObjectContext, PersistenceController.preview.viewContext) }