AddTempTargetRootView.swift 5.2 KB

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