From ec2a7c15c74b1feb5f6ff2656888195d3a2ea27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20F=C3=B6rtsch?= Date: Tue, 13 Aug 2024 00:09:16 +0200 Subject: [PATCH] add minimal generalized main/detail view --- WorkoutsPlus/ContentView.swift | 104 ------------------ WorkoutsPlus/{Exercise.swift => Item.swift} | 4 +- ...etailsView.swift => ItemDetailsView.swift} | 30 ++--- WorkoutsPlus/ItemLibrary.swift | 100 +++++++++++++++++ WorkoutsPlus/WorkoutsPlusApp.swift | 4 +- 5 files changed, 119 insertions(+), 123 deletions(-) delete mode 100644 WorkoutsPlus/ContentView.swift rename WorkoutsPlus/{Exercise.swift => Item.swift} (75%) rename WorkoutsPlus/{ExerciseDetailsView.swift => ItemDetailsView.swift} (58%) create mode 100644 WorkoutsPlus/ItemLibrary.swift diff --git a/WorkoutsPlus/ContentView.swift b/WorkoutsPlus/ContentView.swift deleted file mode 100644 index 68ffd20..0000000 --- a/WorkoutsPlus/ContentView.swift +++ /dev/null @@ -1,104 +0,0 @@ -// -// ContentView.swift -// WorkoutsPlus -// -// Created by Felix Förtsch on 10.08.24. -// - -import SwiftUI -import SwiftData - -struct ContentView: View { - @Environment(\.modelContext) private var modelContext - @Query private var exercises: [Exercise] - - @State private var isAddingNewExercise = false - @State private var selectedExercise: Exercise? - - let initialDataSet = [ - "Pull-up", - "Push-up", - "Dips", - "Rows", - "Split Squat" - ] - - var body: some View { - NavigationSplitView { - List { - ForEach(exercises) { exercise in - NavigationLink { - Text(exercise.name) - } label: { - Text(exercise.name) - } - } - .onDelete(perform: deleteExercises) - } - .onAppear { - if exercises.isEmpty { - loadInitialData(exercises: initialDataSet) - } - } - .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { - Button { - addExercise() - } label: { - Label("Add Exercise", systemImage: "plus") - } - } - } - .sheet(isPresented: $isAddingNewExercise) { - ExerciseDetailsView(exercise: $selectedExercise, isEditing: false) - .onDisappear { - if let selectedExercise = selectedExercise, !selectedExercise.name.isEmpty { - saveNewExercise() - } - } - } - } detail: { - Text("Select an exercise") - } - } - - private func addExercise() { - selectedExercise = Exercise(name: "") - isAddingNewExercise = true - } - - private func saveNewExercise() { - guard let newExercise = selectedExercise else { return } - modelContext.insert(newExercise) - try? modelContext.save() - } - - private func deleteExercises(offsets: IndexSet) { - withAnimation { - for index in offsets { - modelContext.delete(exercises[index]) - } - try? modelContext.save() - } - } - - private func loadInitialData(exercises: [String]) { - var items: [Exercise] = [] - - for exercise in exercises { - let item = Exercise(name: exercise) - items.append(item) - } - - for item in items { - modelContext.insert(item) - } - - try? modelContext.save() - } -} - -#Preview { - ContentView() - .modelContainer(for: Exercise.self, inMemory: true) -} diff --git a/WorkoutsPlus/Exercise.swift b/WorkoutsPlus/Item.swift similarity index 75% rename from WorkoutsPlus/Exercise.swift rename to WorkoutsPlus/Item.swift index c40495a..5b9f234 100644 --- a/WorkoutsPlus/Exercise.swift +++ b/WorkoutsPlus/Item.swift @@ -9,11 +9,11 @@ import Foundation import SwiftData @Model -final class Exercise { +final class Item { var name: String var timestamp: Date - init(name: String, timestamp: Date = Date.now) { + init(name: String = "", timestamp: Date = Date.now) { self.name = name self.timestamp = timestamp } diff --git a/WorkoutsPlus/ExerciseDetailsView.swift b/WorkoutsPlus/ItemDetailsView.swift similarity index 58% rename from WorkoutsPlus/ExerciseDetailsView.swift rename to WorkoutsPlus/ItemDetailsView.swift index dbff858..2783370 100644 --- a/WorkoutsPlus/ExerciseDetailsView.swift +++ b/WorkoutsPlus/ItemDetailsView.swift @@ -7,33 +7,33 @@ import SwiftUI -struct ExerciseDetailsView: View { +struct ItemDetailsView: View { @Environment(\.dismiss) private var dismiss @Environment(\.modelContext) private var modelContext - @Binding var exercise: Exercise? - var isEditing: Bool + var item: Item? + var isPresentedAsSheet: Bool = false var body: some View { - NavigationView { + Form { TextField("Exercise Name", text: Binding( - get: { exercise?.name ?? "" }, + get: { item?.name ?? "" }, set: { newName in - if exercise != nil { - exercise?.name = newName + if item != nil { + item?.name = newName } } )) - } - .navigationTitle(isEditing ? "Edit Exercise" : "Add Exercise") .toolbar { - ToolbarItem(placement: .navigationBarLeading) { - Button("Cancel") { - dismiss() + if (isPresentedAsSheet) { + ToolbarItem(placement: .topBarLeading) { + Button("Cancel") { + dismiss() + } } } - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .topBarTrailing) { Button("Save") { saveItem() dismiss() @@ -56,7 +56,7 @@ struct ExerciseDetailsView: View { struct ExerciseDetailsView_Previews: PreviewProvider { static var previews: some View { - let sampleItem = Exercise(name: "Sample Item") - ExerciseDetailsView(exercise: .constant(sampleItem), isEditing: false) + let sampleItem = Item(name: "Sample Item") + ItemDetailsView(item: sampleItem) } } diff --git a/WorkoutsPlus/ItemLibrary.swift b/WorkoutsPlus/ItemLibrary.swift new file mode 100644 index 0000000..01b09c2 --- /dev/null +++ b/WorkoutsPlus/ItemLibrary.swift @@ -0,0 +1,100 @@ +// +// ContentView.swift +// WorkoutsPlus +// +// Created by Felix Förtsch on 10.08.24. +// + +import SwiftUI +import SwiftData + +struct ItemLibrary: View { + @Environment(\.modelContext) private var modelContext + @Query private var items: [Item] + + @State private var isPresentingNewItemSheet = false + + let initialDataSet = [ + "Pull-up", + "Push-up", + "Dips", + "Rows", + "Split Squat" + ] + + var body: some View { + NavigationView { + List { + ForEach(items) { item in + NavigationLink(destination: ItemDetailsView(item: item)) { + Text(item.name) + } + } + .onDelete(perform: deleteItem) + } + .onAppear { + if items.isEmpty { + loadInitialData(exercises: initialDataSet) + } + } + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button { + createNewItem() + } label: { + Label("Add Exercise", systemImage: "plus") + } + } + } + .sheet(isPresented: $isPresentingNewItemSheet) { + let newItem = Item(name: "") + NavigationView { + ItemDetailsView(item: newItem, isPresentedAsSheet: true) + .onDisappear { + if !newItem.name.isEmpty { + saveItem(item: newItem) + } + } + } + } + } + } + + private func createNewItem() { + isPresentingNewItemSheet = true + } + + private func saveItem(item: Item) { + modelContext.insert(item) + try? modelContext.save() + } + + private func deleteItem(offsets: IndexSet) { + withAnimation { + for index in offsets { + modelContext.delete(items[index]) + } + try? modelContext.save() + } + } + + private func loadInitialData(exercises: [String]) { + var items: [Item] = [] + + for exercise in exercises { + let item = Item(name: exercise) + items.append(item) + } + + for item in items { + modelContext.insert(item) + } + + try? modelContext.save() + } +} + +#Preview { + ItemLibrary() + .modelContainer(for: Item.self, inMemory: true) +} diff --git a/WorkoutsPlus/WorkoutsPlusApp.swift b/WorkoutsPlus/WorkoutsPlusApp.swift index 160d464..698d73d 100644 --- a/WorkoutsPlus/WorkoutsPlusApp.swift +++ b/WorkoutsPlus/WorkoutsPlusApp.swift @@ -12,7 +12,7 @@ import SwiftData struct WorkoutsPlusApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ - Exercise.self, + Item.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) @@ -25,7 +25,7 @@ struct WorkoutsPlusApp: App { var body: some Scene { WindowGroup { - ContentView() + ItemLibrary() } .modelContainer(sharedModelContainer) }