CalibrationsRootView.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import SwiftUI
  2. import Swinject
  3. extension Calibrations {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. private var formatter: NumberFormatter {
  8. let formatter = NumberFormatter()
  9. formatter.numberStyle = .decimal
  10. formatter.maximumFractionDigits = 2
  11. return formatter
  12. }
  13. private var dateFormatter: DateFormatter {
  14. let formatter = DateFormatter()
  15. formatter.timeStyle = .short
  16. formatter.dateStyle = .short
  17. return formatter
  18. }
  19. var body: some View {
  20. GeometryReader { geo in
  21. Form {
  22. Section(header: Text("Add calibration")) {
  23. HStack {
  24. Text("Meter glucose")
  25. Spacer()
  26. TextFieldWithToolBar(text: $state.newCalibration, placeholder: "0", numberFormatter: formatter)
  27. Text(state.units.rawValue).foregroundColor(.secondary)
  28. }
  29. Button {
  30. state.addCalibration()
  31. }
  32. label: { Text("Add") }
  33. .disabled(state.newCalibration <= 0)
  34. }
  35. Section(header: Text("Info")) {
  36. HStack {
  37. Text("Slope")
  38. Spacer()
  39. Text(formatter.string(from: state.slope as NSNumber)!)
  40. }
  41. HStack {
  42. Text("Intercept")
  43. Spacer()
  44. Text(formatter.string(from: state.intercept as NSNumber)!)
  45. }
  46. }
  47. Section(header: Text("Remove")) {
  48. Button {
  49. state.removeLast()
  50. }
  51. label: { Text("Remove Last") }
  52. .disabled(state.calibrations.isEmpty)
  53. Button {
  54. state.removeAll()
  55. }
  56. label: { Text("Remove All") }
  57. .disabled(state.calibrations.isEmpty)
  58. List {
  59. ForEach(state.items) { item in
  60. HStack {
  61. Text(dateFormatter.string(from: item.calibration.date))
  62. Spacer()
  63. VStack(alignment: .leading) {
  64. Text("raw: \(item.calibration.x)")
  65. .font(.caption2)
  66. .foregroundColor(.secondary)
  67. Text("value: \(item.calibration.y)")
  68. .font(.caption2)
  69. .foregroundColor(.secondary)
  70. }
  71. }
  72. }.onDelete(perform: delete)
  73. }
  74. }
  75. if state.calibrations.isNotEmpty {
  76. Section(header: Text("Chart")) {
  77. CalibrationsChart().environmentObject(state)
  78. .frame(minHeight: geo.size.width)
  79. }
  80. }
  81. }
  82. }
  83. .dynamicTypeSize(...DynamicTypeSize.xxLarge)
  84. .onAppear(perform: configureView)
  85. .navigationTitle("Calibrations")
  86. .navigationBarItems(trailing: EditButton().disabled(state.calibrations.isEmpty))
  87. .navigationBarTitleDisplayMode(.automatic)
  88. }
  89. private func delete(at offsets: IndexSet) {
  90. state.removeAtIndex(offsets[offsets.startIndex])
  91. }
  92. }
  93. }