Skip to content

Commit

Permalink
Added recipe list, create views and schema
Browse files Browse the repository at this point in the history
  • Loading branch information
cabmatthew committed Dec 11, 2024
1 parent d07af55 commit 0261f7a
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 6 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file not shown.
Binary file added SwiftFood/.DS_Store
Binary file not shown.
Binary file added SwiftFood/Assets.xcassets/.DS_Store
Binary file not shown.
20 changes: 20 additions & 0 deletions SwiftFood/Schemas/Recipe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,23 @@
//

import Foundation
import SwiftData

@Model
class Recipe: Identifiable {

var id: String
var title: String
var time_required: Float
var servings_amount: Int
var instructions: String

init(title: String, time_required: Float, servings_amount: Int, instructions: String) {

self.id = UUID().uuidString
self.title = title
self.time_required = time_required
self.servings_amount = servings_amount
self.instructions = instructions
}
}
3 changes: 2 additions & 1 deletion SwiftFood/SwiftFoodApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ struct SwiftFoodApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: [MyIngredient.self]) // Attach ModelContainer
// attach the model container, enables the db
.modelContainer(for: [MyIngredient.self, Recipe.self])
}
}
}
6 changes: 6 additions & 0 deletions SwiftFood/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ struct ContentView: View {
.accessibilityIdentifier("ToIngredients")
.buttonStyle(.borderedProminent)
.padding(.bottom)
NavigationLink("View your recipes!") {
RecipeList()
}
.accessibilityIdentifier("ToRecipes")
.buttonStyle(.borderedProminent)
.padding(.bottom)
}
.padding()
}
Expand Down
10 changes: 5 additions & 5 deletions SwiftFood/Views/MyIngredientList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
// Created by Matthew Caballero on 12/7/24.
//

// Test change

import SwiftUI
import SwiftData

Expand Down Expand Up @@ -59,6 +57,7 @@ struct MyIngredientList: View {

List {
// For each ingredient in myingredient context
// Gets each ingredient of ingredient entity from the database
ForEach(myIngredients) { ingredient in
HStack {
VStack(alignment: .leading) {
Expand All @@ -79,24 +78,25 @@ struct MyIngredientList: View {
Image(systemName: "trash")
.foregroundColor(.red)
}
.buttonStyle(.borderless) // To avoid affecting list row interaction
.buttonStyle(.borderless)
}
}
}
.cornerRadius(20)
}
.padding()
}

func addIngredient() {
guard !title.isEmpty, !unit.isEmpty else { return } // Prevent empty input
guard !title.isEmpty, !unit.isEmpty else { return } // No empty fields
let ingredient = MyIngredient(
title: title,
amount: amount,
unit: unit
)
context.insert(ingredient)

// Resetting input fields
// Reset input fields when done
title = ""
amount = 0
unit = ""
Expand Down
105 changes: 105 additions & 0 deletions SwiftFood/Views/RecipeCreate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//
// RecipeCreate.swift
// SwiftFood
//
// Created by Matthew Caballero on 12/11/24.
//

import SwiftUI
import SwiftData

struct RecipeCreate: View {
@Environment(\.modelContext) private var context
@Environment(\.dismiss) private var dismiss

@Query private var myRecipes: [Recipe]

@State private var title: String = ""
@State private var time_required: Float = 0.0
@State private var servings_amount: Int = 0
@State private var instructions: String = ""

// Used below for the number field, to show decimal correctly
private var decimalFormatter: NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
return formatter
}

var body: some View {
VStack {
Text("My Ingredients")
.font(.headline)

// Text input fields
// Uses accessibility identifiers, easy to access during testing
VStack(alignment: .leading, spacing: 10) {
HStack {
Text("Title: ")
TextField("Recipe Title", text: $title)
.accessibilityIdentifier("CreateRecipeTitle")
.textFieldStyle(.roundedBorder)
.frame(width: 110)
}
HStack {
Text("Time Required:")
TextField("Time Required", value: $time_required, formatter: decimalFormatter)
.accessibilityIdentifier("CreateRecipeTimeRequired")
.textFieldStyle(.roundedBorder)
.keyboardType(.decimalPad)
.frame(width: 40)
Text("hours")
}
HStack {
Text("Number of Servings: ")
TextField("Number of Servings", value: $servings_amount, formatter: NumberFormatter())
.accessibilityIdentifier("CreateRecipeServingsAmount")
.textFieldStyle(.roundedBorder)
.keyboardType(.numberPad)
.frame(width: 40)
Text("servings")
}
Text("Instructions: ")
ScrollView {
TextEditor(text: $instructions)
.accessibilityIdentifier("CreateRecipeInstructions")
.frame(height: 150) // Fixed height
.cornerRadius(8)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray))
}
}
// Add button
Button("Add Recipe") {
// Trigger add recipe function
addRecipe()
// Close current view / go back in the nav stack
dismiss()
}
.accessibilityIdentifier("AddRecipeButton")
.buttonStyle(.borderedProminent)
}
}

func addRecipe() {
guard !title.isEmpty, time_required > 0, servings_amount > 0, !instructions.isEmpty else { return } // No empty inputs
let recipe = Recipe(
title: title,
time_required: time_required,
servings_amount: servings_amount,
instructions: instructions
)
context.insert(recipe)

// Resetting input fields
title = ""
time_required = 0.0
servings_amount = 0
instructions = ""
}
}

#Preview {
ContentView()
}
62 changes: 62 additions & 0 deletions SwiftFood/Views/RecipeList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// RecipeList.swift
// SwiftFood
//
// Created by Matthew Caballero on 12/11/24.
//

import SwiftUI
import SwiftData

struct RecipeList: View {
@Environment(\.modelContext) private var context
@Query private var myRecipes: [Recipe]

var body: some View {
VStack {
Text("My Recipes")
.font(.headline)

List {
// For each recipe in recipes context
ForEach(myRecipes) { recipe in
HStack {
VStack(alignment: .leading) {
Text(recipe.title)
.font(.headline)
// Formatting to show the decimal correctly
Text("\(String(format: "%.1f", recipe.time_required)) hours")
Text("\(recipe.servings_amount) servings")
}
Spacer()

// Delete Button
Button(action: {
deleteItem(recipe)
}) {
Image(systemName: "trash")
.foregroundColor(.red)
}
.buttonStyle(.borderless)
}
}
}
.cornerRadius(20)
NavigationLink("Create new recipe!") {
RecipeCreate()
}
.accessibilityIdentifier("ToRecipeCreate")
.buttonStyle(.borderedProminent)
.padding(.bottom)
}
.padding()
}

func deleteItem(_ recipe: Recipe) {
context.delete(recipe)
}
}

#Preview {
ContentView()
}

0 comments on commit 0261f7a

Please sign in to comment.