This commit is contained in:
2025-07-15 16:33:55 -04:00
parent 39fd45e03f
commit 48bbbbf692
8 changed files with 242 additions and 85 deletions

View File

@ -0,0 +1,59 @@
//
// SplitExerciseAssignment.swift
// Workouts
//
// Created by rzen on 7/15/25 at 7:12AM.
//
// Copyright 2025 Rouslan Zenetl. All Rights Reserved.
//
import SwiftUI
struct SplitExerciseAssignmentAddEditView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@State var model: SplitExerciseAssignment
var body: some View {
NavigationStack {
Form {
Section(header: Text("Sets/Reps")) {
Stepper("Sets: \(model.sets)", value: $model.sets, in: 1...10)
Stepper("Reps: \(model.reps)", value: $model.reps, in: 1...50)
}
// Weight section
Section(header: Text("Weight")) {
HStack {
VStack(alignment: .center) {
Text("\(model.weight) lbs")
.font(.headline)
}
Spacer()
VStack(alignment: .trailing) {
Stepper("±1", value: $model.weight, in: 0...1000)
Stepper("±5", value: $model.weight, in: 0...1000, step: 5)
}
.frame(width: 130)
}
}
}
.navigationTitle("\(model.exercise?.name ?? Exercise.unnamed)")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {
dismiss()
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("Save") {
try? modelContext.save()
dismiss()
}
}
}
}
}
}

View File

@ -14,7 +14,9 @@ struct ExercisePickerView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Query(sort: [SortDescriptor(\Exercise.name)]) private var exercises: [Exercise]
@Query(sort: [SortDescriptor(\ExerciseType.name)]) private var exerciseTypes: [ExerciseType]
// @Query(sort: [SortDescriptor(\Exercise.name)]) private var exercises: [Exercise]
var onExerciseSelected: (Exercise) -> Void
@ -22,18 +24,24 @@ struct ExercisePickerView: View {
NavigationStack {
VStack {
Form {
Section (header: Text("This Split")) {
List {
ForEach(exercises) { exercise in
Button(action: {
onExerciseSelected(exercise)
dismiss()
}) {
ListItem(title: exercise.name)
ForEach (exerciseTypes) { exerciseType in
if let exercises = exerciseType.exercises, !exercises.isEmpty {
let sortedExercises = exercises.sorted(by: { $0.name < $1.name })
Section (header: Text("\(exerciseType.name)")) {
List {
ForEach(sortedExercises) { exercise in
Button(action: {
onExerciseSelected(exercise)
dismiss()
}) {
ListItem(text: exercise.name)
}
.buttonStyle(.plain)
}
}
.buttonStyle(.plain)
}
}
}
}
}

View File

@ -15,14 +15,14 @@ struct WorkoutEditView: View {
@Environment(\.dismiss) private var dismiss
@State var workout: Workout
@State var endDateHidden: Bool = false
@State var workoutEndDate: Date = Date()
var body: some View {
NavigationStack {
Form {
Section (header: Text("Split")) {
Text("\(workout.split?.name ?? Split.unnamed)")
}
// Section (header: Text("Split")) {
// Text("\(workout.split?.name ?? Split.unnamed)")
// }
Section (header: Text("Start/End")) {
DatePicker("Started", selection: $workout.start)
@ -31,38 +31,35 @@ struct WorkoutEditView: View {
set: { newValue in
withAnimation {
if newValue {
workout.end = Date()
endDateHidden = false
workoutEndDate = Date()
workout.end = workoutEndDate
} else {
workout.end = nil
endDateHidden = true
}
}
}
))
if !endDateHidden {
DatePicker("Ended", selection: $workout.start)
if workout.end != nil {
DatePicker("Ended", selection: $workoutEndDate)
}
}
.onAppear {
endDateHidden = workout.end == nil
}
Section (header: Text("Workout Log")) {
if let workoutLogs = workout.logs {
List {
ForEach (workoutLogs) { log in
ListItem(
title: log.exercise?.name ?? Exercise.unnamed,
subtitle: "\(log.sets) sets × \(log.reps) reps × \(log.weight) lbs"
)
}
}
} else {
Text("No workout logs yet")
}
}
// Section (header: Text("Workout Log")) {
// if let workoutLogs = workout.logs {
// List {
// ForEach (workoutLogs) { log in
// ListItem(
// title: log.exercise?.name ?? Exercise.unnamed,
// subtitle: "\(log.sets) sets × \(log.reps) reps × \(log.weight) lbs"
// )
// }
// }
// } else {
// Text("No workout logs yet")
// }
// }
}
.navigationTitle("\(workout.split?.name ?? Split.unnamed) Split")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {

View File

@ -20,7 +20,9 @@ struct WorkoutLogView: View {
var sortedWorkoutLogs: [WorkoutLog] {
if let logs = workout.logs {
logs.sorted(by: { $0.exercise!.name < $1.exercise!.name })
logs.sorted(by: {
$0.completed == $1.completed ? $0.exercise!.name < $1.exercise!.name : !$0.completed
})
} else {
[]
}
@ -43,16 +45,20 @@ struct WorkoutLogView: View {
.swipeActions(edge: .leading, allowsFullSwipe: false) {
if (log.completed) {
Button {
log.completed = false
try? modelContext.save()
withAnimation {
log.completed = false
try? modelContext.save()
}
} label: {
Label("Complete", systemImage: "circle.fill")
}
.tint(.green)
} else {
Button {
log.completed = true
try? modelContext.save()
withAnimation {
log.completed = true
try? modelContext.save()
}
} label: {
Label("Reset", systemImage: "checkmark.circle.fill")
}
@ -76,7 +82,7 @@ struct WorkoutLogView: View {
}
}
}
.navigationTitle("\(workout.split?.name ?? Split.unnamed)")
.navigationTitle("\(workout.split?.name ?? Split.unnamed) Split")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: { showingAddSheet.toggle() }) {