AddTempTargetRootView.swift 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import SwiftUI
  2. import Swinject
  3. extension AddTempTarget {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. @State private var isPromtPresented = false
  8. @State private var isRemoveAlertPresented = false
  9. @State private var removeAlert: Alert?
  10. private var formatter: NumberFormatter {
  11. let formatter = NumberFormatter()
  12. formatter.numberStyle = .decimal
  13. formatter.maximumFractionDigits = 1
  14. return formatter
  15. }
  16. var body: some View {
  17. Form {
  18. if !state.presets.isEmpty {
  19. Section(header: Text("Presets")) {
  20. ForEach(state.presets) { preset in
  21. presetView(for: preset)
  22. }
  23. }
  24. }
  25. Section(header: Text("Custom")) {
  26. HStack {
  27. Text("Bottom target")
  28. Spacer()
  29. DecimalTextField("0", value: $state.low, formatter: formatter, cleanInput: true)
  30. Text(state.units.rawValue).foregroundColor(.secondary)
  31. }
  32. HStack {
  33. Text("Top target")
  34. Spacer()
  35. DecimalTextField("0", value: $state.high, formatter: formatter, cleanInput: true)
  36. Text(state.units.rawValue).foregroundColor(.secondary)
  37. }
  38. HStack {
  39. Text("Duration")
  40. Spacer()
  41. DecimalTextField("0", value: $state.duration, formatter: formatter, cleanInput: true)
  42. Text("minutes").foregroundColor(.secondary)
  43. }
  44. DatePicker("Date", selection: $state.date)
  45. Button { isPromtPresented = true }
  46. label: { Text("Save as preset") }
  47. }
  48. Section {
  49. Button { state.enact() }
  50. label: { Text("Enact") }
  51. Button { state.cancel() }
  52. label: { Text("Cancel Temp Target") }
  53. }
  54. }
  55. .popover(isPresented: $isPromtPresented) {
  56. Form {
  57. Section(header: Text("Enter preset name")) {
  58. TextField("Name", text: $state.newPresetName)
  59. Button {
  60. state.save()
  61. isPromtPresented = false
  62. }
  63. label: { Text("Save") }
  64. Button { isPromtPresented = false }
  65. label: { Text("Cancel") }
  66. }
  67. }
  68. }
  69. .onAppear(perform: configureView)
  70. .navigationTitle("Enact Temp Target")
  71. .navigationBarTitleDisplayMode(.automatic)
  72. .navigationBarItems(leading: Button("Close", action: state.hideModal))
  73. }
  74. private func presetView(for preset: TempTarget) -> some View {
  75. var low = preset.targetBottom
  76. var high = preset.targetTop
  77. if state.units == .mmolL {
  78. low = low?.asMmolL
  79. high = high?.asMmolL
  80. }
  81. return HStack {
  82. VStack {
  83. HStack {
  84. Text(preset.displayName)
  85. Spacer()
  86. }
  87. HStack {
  88. Text(
  89. "\(formatter.string(from: (low ?? 0) as NSNumber)!) - \(formatter.string(from: (high ?? 0) as NSNumber)!)"
  90. )
  91. .foregroundColor(.secondary)
  92. .font(.caption)
  93. Text(state.units.rawValue)
  94. .foregroundColor(.secondary)
  95. .font(.caption)
  96. Text("for \(formatter.string(from: preset.duration as NSNumber)!) min")
  97. .foregroundColor(.secondary)
  98. .font(.caption)
  99. Spacer()
  100. }.padding(.top, 2)
  101. }
  102. .contentShape(Rectangle())
  103. .onTapGesture {
  104. state.enactPreset(id: preset.id)
  105. }
  106. Image(systemName: "xmark.circle").foregroundColor(.secondary)
  107. .contentShape(Rectangle())
  108. .padding(.vertical)
  109. .onTapGesture {
  110. removeAlert = Alert(
  111. title: Text("Are you sure?"),
  112. message: Text("Delete preset \"\(preset.displayName)\""),
  113. primaryButton: .destructive(Text("Delete"), action: { state.removePreset(id: preset.id) }),
  114. secondaryButton: .cancel()
  115. )
  116. isRemoveAlertPresented = true
  117. }
  118. .alert(isPresented: $isRemoveAlertPresented) {
  119. removeAlert!
  120. }
  121. }
  122. }
  123. }
  124. }