add ModelContainerPreview conecept, move SampleData, fix Exercise, ExerciseUnit, ExerciseType

This commit is contained in:
Felix Förtsch
2024-11-13 13:59:39 +01:00
parent 370e070fcd
commit 02e2937094
11 changed files with 211 additions and 63 deletions

View File

@@ -17,8 +17,8 @@ struct AddExercise: View {
@State private var name: String = ""
@State private var description: String = ""
@State private var type = ExerciseType("")
@State private var unit = ExerciseUnit("", symbol: "")
@State private var type: ExerciseType?
@State private var unit: ExerciseUnit?
@State private var isPartOfProgression: Bool = false
@@ -41,12 +41,14 @@ struct AddExercise: View {
• Sprint → Time or Distance
""")) {
Picker("Exercise Type", selection: $type) {
Text("None").tag(nil as ExerciseType?)
ForEach(exerciseTypes, id: \.self) { type in
Text("\(type.name)").tag(type as ExerciseType?)
}
}
.pickerStyle(NavigationLinkPickerStyle())
Picker("Exercise Unit", selection: $unit) {
Text("None").tag(nil as ExerciseUnit?)
ForEach(exerciseUnits, id: \.self) { unit in
Text("\(unit.name) (\(unit.symbol))").tag(unit as ExerciseUnit?)
}
@@ -66,7 +68,7 @@ struct AddExercise: View {
ToolbarItem(placement: .confirmationAction) {
Button("Save") {
withAnimation {
save()
saveNew()
dismiss()
}
}
@@ -76,7 +78,7 @@ struct AddExercise: View {
}
}
private func save() {
private func saveNew() {
let exerciseToSave = Exercise(name)
modelContext.insert(exerciseToSave)

View File

@@ -37,32 +37,3 @@ final class Exercise: Nameable {
self.name = name
}
}
extension Exercise {
static let sampleDataRecommendedRoutine: [Exercise] = [
Exercise("Shoulder Band Warm-up"),
Exercise("Squat Sky Reaches"),
Exercise("GMB Wrist Prep"),
Exercise("Dead Bugs"),
Exercise("Pull-up Progression"),
Exercise("Dip Progression"),
Exercise("Squat Progression"),
Exercise("Hinge Progression"),
Exercise("Row Progression"),
Exercise("Push-up Progression"),
Exercise("Handstand Practice"),
Exercise("Support Practice")
]
static let sampleDataRings: [Exercise] = [
Exercise("Dips"),
Exercise("Chin-ups"),
Exercise("Push-ups"),
Exercise("Inverted Rows"),
Exercise("Hanging Knee Raises"),
Exercise("Pistol Squats"),
Exercise("Hanging Leg Curls"),
Exercise("Sissy Squats")
]
}

View File

@@ -8,11 +8,13 @@
import SwiftUI
import SwiftData
struct ExerciseDetail: View {
struct ExerciseEditor: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var modelContext
@State var exercise: Exercise
@State private var name: String = ""
@State private var description: String = ""
@State private var isPartOfProgression: Bool = false
@@ -25,7 +27,7 @@ struct ExerciseDetail: View {
var body: some View {
Form {
Section {
TextField("Exercise Name", text: $exercise.name)
TextField("Exercise Name", text: $name)
TextEditorWithPlaceholder(text: $description, placeholder: "Description (optional)")
}
Section(footer: Text("""
@@ -35,12 +37,14 @@ struct ExerciseDetail: View {
Sprint Time or Distance
""")) {
Picker("Exercise Type", selection: $type) {
Text("None").tag(nil as ExerciseType?)
ForEach(exerciseTypes, id: \.self) { type in
Text("\(type.name)").tag(type as ExerciseType?)
}
}
.pickerStyle(NavigationLinkPickerStyle())
Picker("Exercise Unit", selection: $unit) {
Text("None").tag(nil as ExerciseUnit?)
ForEach(exerciseUnits, id: \.self) { unit in
Text("\(unit.name) (\(unit.symbol))").tag(unit as ExerciseUnit?)
}
@@ -59,26 +63,37 @@ struct ExerciseDetail: View {
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Save") {
saveItem()
saveExisting()
dismiss()
}
}
}
}
private func saveItem() {
if modelContext.hasChanges {
do {
try modelContext.save()
} catch {
print("Failed to save exercise: \(error.localizedDescription)")
.onAppear() {
name = exercise.name
description = exercise.exerciseDescription
isPartOfProgression = exercise.isPartOfProgression
if let type = exercise.type {
self.type = type
}
if let unit = exercise.unit {
self.unit = unit
}
}
}
private func saveExisting() {
exercise.name = name
exercise.exerciseDescription = description
exercise.isPartOfProgression = isPartOfProgression
exercise.type = type
exercise.unit = unit
}
}
#Preview {
NavigationStack {
ExerciseDetail(exercise: Exercise("Squat Sky Reaches"))
ModelContainerPreview(ModelContainer.sample) {
NavigationStack {
ExerciseEditor(exercise: Exercise.sampleDataRecommendedRoutine.first!)
}
}
}

View File

@@ -31,7 +31,7 @@ struct ExerciseLibrary: View {
List {
Section {
ForEach(filteredItems) { exercise in
NavigationLink(destination: ExerciseDetail(exercise: exercise), label: {Text(exercise.name)})
NavigationLink(destination: ExerciseEditor(exercise: exercise), label: {Text(exercise.name)})
}
.onDelete(perform: deleteExercise)
if filteredItems.isEmpty {
@@ -77,6 +77,14 @@ struct ExerciseLibrary: View {
}
}
#Preview {
ModelContainerPreview(ModelContainer.sample) {
NavigationStack {
ExerciseLibrary()
}
}
}
#Preview("With Sample Data") {
NavigationStack {
ExerciseLibrary()

View File

@@ -19,11 +19,3 @@ final class ExerciseType: Identifiable {
self.name = name
}
}
extension ExerciseType {
static let getTypes = [
ExerciseType("Kilograms"),
ExerciseType("Kilometers"),
ExerciseType("Meters"),
]
}

View File

@@ -21,11 +21,3 @@ final class ExerciseUnit: Unit, Identifiable {
self.symbol = symbol
}
}
extension ExerciseUnit {
static let getUnits = [
ExerciseUnit("Kilograms", symbol: "kg"),
ExerciseUnit("Kilometers", symbol: "km"),
ExerciseUnit("Meters", symbol: "m"),
]
}