AddCarbsRootView.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import CoreData
  2. import SwiftUI
  3. import Swinject
  4. extension AddCarbs {
  5. struct RootView: BaseView {
  6. let resolver: Resolver
  7. @StateObject var state = StateModel()
  8. @State var dish: String = ""
  9. @State var isPromtPresented = false
  10. @State var saved = false
  11. @FetchRequest(
  12. entity: Presets.entity(),
  13. sortDescriptors: [NSSortDescriptor(key: "dish", ascending: true)]
  14. ) var carbPresets: FetchedResults<Presets>
  15. @Environment(\.managedObjectContext) var moc
  16. private var formatter: NumberFormatter {
  17. let formatter = NumberFormatter()
  18. formatter.numberStyle = .decimal
  19. formatter.maximumFractionDigits = 1
  20. return formatter
  21. }
  22. var body: some View {
  23. Form {
  24. if let carbsReq = state.carbsRequired {
  25. Section {
  26. HStack {
  27. Text("Carbs required")
  28. Spacer()
  29. Text(formatter.string(from: carbsReq as NSNumber)! + " g")
  30. }
  31. }
  32. }
  33. Section {
  34. Section {
  35. HStack {
  36. Text("Carbs").fontWeight(.semibold)
  37. Spacer()
  38. DecimalTextField("0", value: $state.carbs, formatter: formatter, autofocus: true, cleanInput: true)
  39. Text("grams").foregroundColor(.secondary)
  40. }.padding(.vertical)
  41. if state.useFPU {
  42. HStack {
  43. Text("Protein").foregroundColor(.loopRed).fontWeight(.thin)
  44. Spacer()
  45. DecimalTextField(
  46. "0",
  47. value: $state.protein,
  48. formatter: formatter,
  49. autofocus: false,
  50. cleanInput: true
  51. ).foregroundColor(.loopRed)
  52. Text("grams").foregroundColor(.secondary)
  53. }
  54. HStack {
  55. Text("Fat").foregroundColor(.loopYellow).fontWeight(.thin)
  56. Spacer()
  57. DecimalTextField(
  58. "0",
  59. value: $state.fat,
  60. formatter: formatter,
  61. autofocus: false,
  62. cleanInput: true
  63. )
  64. Text("grams").foregroundColor(.secondary)
  65. }
  66. HStack {
  67. Button {
  68. isPromtPresented = true
  69. }
  70. label: { Text("Save as Preset") }
  71. }
  72. .frame(maxWidth: .infinity, alignment: .trailing)
  73. .disabled(state.carbs <= 0 && state.fat <= 0 && state.protein <= 0)
  74. .popover(isPresented: $isPromtPresented) {
  75. presetPopover
  76. }
  77. }
  78. DatePicker("Date", selection: $state.date)
  79. }
  80. }
  81. Section {
  82. Button { state.add() }
  83. label: { Text("Save and continue") }
  84. .disabled(state.carbs <= 0 && state.fat <= 0 && state.protein <= 0)
  85. }
  86. if state.useFPU {
  87. mealPresets
  88. }
  89. }
  90. .onAppear(perform: configureView)
  91. .navigationBarItems(leading: Button("Close", action: state.hideModal))
  92. }
  93. var presetPopover: some View {
  94. Form {
  95. Section(header: Text("Enter Meal Preset Name")) {
  96. TextField("Name Of Dish", text: $dish)
  97. Button {
  98. saved = true
  99. if dish != "", saved {
  100. let preset = Presets(context: moc)
  101. preset.dish = dish
  102. preset.fat = state.fat as NSDecimalNumber
  103. preset.protein = state.protein as NSDecimalNumber
  104. preset.carbs = state.carbs as NSDecimalNumber
  105. try? moc.save()
  106. state.selection = preset
  107. saved = false
  108. isPromtPresented = false
  109. }
  110. }
  111. label: { Text("Save") }
  112. Button {
  113. dish = ""
  114. saved = false
  115. isPromtPresented = false }
  116. label: { Text("Cancel") }
  117. }
  118. }
  119. }
  120. var mealPresets: some View {
  121. Section {
  122. VStack {
  123. Picker("Meal Presets", selection: $state.selection) {
  124. Text("Empty").tag(nil as Presets?)
  125. ForEach(carbPresets, id: \.self) { (preset: Presets) in
  126. Text(preset.dish ?? "").tag(preset as Presets?)
  127. }
  128. }
  129. .pickerStyle(.automatic)
  130. ._onBindingChange($state.selection) { _ in
  131. state.carbs = ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
  132. state.fat = ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
  133. state.protein = ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
  134. }
  135. }
  136. Button {
  137. state.deletePreset()
  138. }
  139. label: { Text("Delete Selected Preset") }
  140. .disabled(state.selection == nil)
  141. }
  142. }
  143. }
  144. }