CalibrationsRootView.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import SwiftUI
  2. import Swinject
  3. extension Calibrations {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. @Environment(\.colorScheme) var colorScheme
  8. var color: LinearGradient {
  9. colorScheme == .dark ? LinearGradient(
  10. gradient: Gradient(colors: [
  11. Color.bgDarkBlue,
  12. Color.bgDarkerDarkBlue
  13. ]),
  14. startPoint: .top,
  15. endPoint: .bottom
  16. )
  17. :
  18. LinearGradient(
  19. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  20. startPoint: .top,
  21. endPoint: .bottom
  22. )
  23. }
  24. private var formatter: NumberFormatter {
  25. let formatter = NumberFormatter()
  26. formatter.numberStyle = .decimal
  27. formatter.maximumFractionDigits = 2
  28. return formatter
  29. }
  30. private var dateFormatter: DateFormatter {
  31. let formatter = DateFormatter()
  32. formatter.timeStyle = .short
  33. formatter.dateStyle = .short
  34. return formatter
  35. }
  36. var body: some View {
  37. GeometryReader { geo in
  38. Form {
  39. Section(header: Text("Add calibration")) {
  40. HStack {
  41. Text("Meter glucose")
  42. Spacer()
  43. DecimalTextField(
  44. "0",
  45. value: $state.newCalibration,
  46. formatter: formatter,
  47. autofocus: false,
  48. cleanInput: true
  49. )
  50. Text(state.units.rawValue).foregroundColor(.secondary)
  51. }
  52. Button {
  53. state.addCalibration()
  54. }
  55. label: { Text("Add") }
  56. .disabled(state.newCalibration <= 0)
  57. }
  58. Section(header: Text("Info")) {
  59. HStack {
  60. Text("Slope")
  61. Spacer()
  62. Text(formatter.string(from: state.slope as NSNumber)!)
  63. }
  64. HStack {
  65. Text("Intercept")
  66. Spacer()
  67. Text(formatter.string(from: state.intercept as NSNumber)!)
  68. }
  69. }
  70. Section(header: Text("Remove")) {
  71. Button {
  72. state.removeLast()
  73. }
  74. label: { Text("Remove Last") }
  75. .disabled(state.calibrations.isEmpty)
  76. Button {
  77. state.removeAll()
  78. }
  79. label: { Text("Remove All") }
  80. .disabled(state.calibrations.isEmpty)
  81. List {
  82. ForEach(state.items) { item in
  83. HStack {
  84. Text(dateFormatter.string(from: item.calibration.date))
  85. Spacer()
  86. VStack(alignment: .leading) {
  87. Text("raw: \(item.calibration.x)")
  88. .font(.caption2)
  89. .foregroundColor(.secondary)
  90. Text("value: \(item.calibration.y)")
  91. .font(.caption2)
  92. .foregroundColor(.secondary)
  93. }
  94. }
  95. }.onDelete(perform: delete)
  96. }
  97. }
  98. if state.calibrations.isNotEmpty {
  99. Section(header: Text("Chart")) {
  100. CalibrationsChart().environmentObject(state)
  101. .frame(minHeight: geo.size.width)
  102. }
  103. }
  104. }
  105. }
  106. .scrollContentBackground(.hidden).background(color)
  107. .onAppear(perform: configureView)
  108. .navigationTitle("Calibrations")
  109. .navigationBarItems(trailing: EditButton().disabled(state.calibrations.isEmpty))
  110. .navigationBarTitleDisplayMode(.automatic)
  111. }
  112. private func delete(at offsets: IndexSet) {
  113. state.removeAtIndex(offsets[offsets.startIndex])
  114. }
  115. }
  116. }