/ BalanceKit / MealPresetView.swift
MealPresetView.swift
1 // 2 // MealPresetView.swift 3 // BalanceKit 4 // 5 // Created by Alexander Kunau on 12.07.25. 6 // 7 8 import SwiftUI 9 10 struct MealPresetView: View { 11 @Environment(\.dismiss) private var dismiss 12 @ObservedObject var dataManager: FoodDataManager 13 14 @State private var presetName = "" 15 @State private var selectedMealType: MealType = .breakfast 16 @State private var foodItems: [PresetFoodItem] = [] 17 18 @State private var showingAddFood = false 19 @State private var newFoodName = "" 20 @State private var newFoodCalories = "" 21 @State private var newFoodProtein = "" 22 @State private var newFoodCarbs = "" 23 @State private var newFoodFat = "" 24 25 var body: some View { 26 NavigationStack { 27 Form { 28 Section(header: Text("Vorlage Details")) { 29 TextField("Name der Vorlage", text: $presetName) 30 31 Picker("Mahlzeit", selection: $selectedMealType) { 32 ForEach(MealType.allCases, id: \.self) { type in 33 Label(type.rawValue, systemImage: type.icon) 34 } 35 } 36 } 37 38 Section(header: VStack(alignment: .leading, spacing: 4) { 39 HStack { 40 Text("Nahrungsmittel") 41 Spacer() 42 Text("\(totalCalories) kcal") 43 .fontWeight(.bold) 44 .foregroundColor(.green) 45 } 46 47 HStack(spacing: 12) { 48 Label("\(String(format: "%.1f", totalProtein))g", systemImage: "p.circle") 49 .font(.caption) 50 .foregroundColor(.blue) 51 52 Label("\(String(format: "%.1f", totalCarbs))g", systemImage: "c.circle") 53 .font(.caption) 54 .foregroundColor(.orange) 55 56 Label("\(String(format: "%.1f", totalFat))g", systemImage: "f.circle") 57 .font(.caption) 58 .foregroundColor(.purple) 59 } 60 }) { 61 if foodItems.isEmpty { 62 Text("Keine Nahrungsmittel hinzugefügt") 63 .foregroundColor(.secondary) 64 .italic() 65 } else { 66 ForEach(foodItems) { item in 67 VStack(alignment: .leading, spacing: 4) { 68 HStack { 69 Text(item.name) 70 Spacer() 71 Text("\(item.calories) kcal") 72 .foregroundColor(.secondary) 73 } 74 75 HStack(spacing: 12) { 76 Text("P: \(String(format: "%.1f", item.protein))g") 77 .font(.caption) 78 .foregroundColor(.blue) 79 80 Text("K: \(String(format: "%.1f", item.carbs))g") 81 .font(.caption) 82 .foregroundColor(.orange) 83 84 Text("F: \(String(format: "%.1f", item.fat))g") 85 .font(.caption) 86 .foregroundColor(.purple) 87 } 88 } 89 } 90 .onDelete { indexSet in 91 foodItems.remove(atOffsets: indexSet) 92 } 93 } 94 95 Button("Nahrungsmittel hinzufügen") { 96 showingAddFood = true 97 } 98 } 99 100 Section { 101 Button("Vorlage speichern") { 102 savePreset() 103 } 104 .disabled(presetName.isEmpty || foodItems.isEmpty) 105 } 106 } 107 .navigationTitle("Mahlzeiten-Vorlage") 108 .toolbar { 109 ToolbarItem(placement: .cancellationAction) { 110 Button("Abbrechen") { 111 dismiss() 112 } 113 } 114 } 115 .sheet(isPresented: $showingAddFood) { 116 NavigationStack { 117 Form { 118 Section(header: Text("Neues Nahrungsmittel")) { 119 TextField("Name", text: $newFoodName) 120 121 TextField("Kalorien", text: $newFoodCalories) 122 .keyboardType(.numberPad) 123 124 TextField("Protein (g)", text: $newFoodProtein) 125 .keyboardType(.decimalPad) 126 127 TextField("Kohlenhydrate (g)", text: $newFoodCarbs) 128 .keyboardType(.decimalPad) 129 130 TextField("Fett (g)", text: $newFoodFat) 131 .keyboardType(.decimalPad) 132 } 133 134 Section { 135 Button("Hinzufügen") { 136 addFoodToPreset() 137 } 138 .disabled(newFoodName.isEmpty || newFoodCalories.isEmpty) 139 } 140 } 141 .navigationTitle("Nahrungsmittel hinzufügen") 142 .toolbar { 143 ToolbarItem(placement: .cancellationAction) { 144 Button("Abbrechen") { 145 showingAddFood = false 146 } 147 } 148 } 149 } 150 } 151 } 152 } 153 154 private var totalCalories: Int { 155 foodItems.reduce(0) { $0 + $1.calories } 156 } 157 158 private var totalProtein: Double { 159 foodItems.reduce(0) { $0 + $1.protein } 160 } 161 162 private var totalCarbs: Double { 163 foodItems.reduce(0) { $0 + $1.carbs } 164 } 165 166 private var totalFat: Double { 167 foodItems.reduce(0) { $0 + $1.fat } 168 } 169 170 private func addFoodToPreset() { 171 if let calories = Int(newFoodCalories), !newFoodName.isEmpty { 172 let protein = Double(newFoodProtein) ?? 0 173 let carbs = Double(newFoodCarbs) ?? 0 174 let fat = Double(newFoodFat) ?? 0 175 176 let newItem = PresetFoodItem( 177 name: newFoodName, 178 calories: calories, 179 protein: protein, 180 carbs: carbs, 181 fat: fat 182 ) 183 foodItems.append(newItem) 184 newFoodName = "" 185 newFoodCalories = "" 186 newFoodProtein = "" 187 newFoodCarbs = "" 188 newFoodFat = "" 189 showingAddFood = false 190 } 191 } 192 193 private func savePreset() { 194 if !presetName.isEmpty && !foodItems.isEmpty { 195 dataManager.createPreset(name: presetName, mealType: selectedMealType, foods: foodItems) 196 dismiss() 197 } 198 } 199 } 200 201 #Preview { 202 MealPresetView(dataManager: FoodDataManager()) 203 }