DexcomConnectStepView.swift 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // LoopFollow
  2. // DexcomConnectStepView.swift
  3. import SwiftUI
  4. struct DexcomConnectStepView: View {
  5. @ObservedObject var viewModel: DexcomSettingsViewModel
  6. @ObservedObject var onboarding: OnboardingViewModel
  7. var body: some View {
  8. VStack(spacing: 0) {
  9. ConnectionStatusPill(
  10. color: statusColor,
  11. message: viewModel.statusMessage,
  12. isLoading: viewModel.statusKind == .checking,
  13. systemImage: statusIcon
  14. )
  15. .padding(.horizontal)
  16. .padding(.top, 12)
  17. .padding(.bottom, 8)
  18. .animation(.easeInOut(duration: 0.25), value: viewModel.statusKind)
  19. form
  20. OnboardingNavFooter(
  21. continueEnabled: viewModel.canVerifyProceed,
  22. showBack: onboarding.canGoBack,
  23. onBack: { onboarding.goBack() },
  24. onContinue: { onboarding.advance() }
  25. )
  26. }
  27. }
  28. private var form: some View {
  29. Form {
  30. Section {
  31. EmptyView()
  32. } header: {
  33. OnboardingStepHeader(
  34. systemImage: "sensor.tag.radiowaves.forward.fill",
  35. title: "Connect Dexcom Share",
  36. subtitle: "Sign in with the Dexcom Share account that shares glucose data."
  37. )
  38. .textCase(nil)
  39. .padding(.bottom, 8)
  40. }
  41. .listRowInsets(EdgeInsets())
  42. .listRowBackground(Color.clear)
  43. Section(header: Text("Dexcom Share")) {
  44. HStack {
  45. Text("Username")
  46. TextField("Enter Username", text: $viewModel.userName)
  47. .textContentType(.username)
  48. .autocapitalization(.none)
  49. .disableAutocorrection(true)
  50. .multilineTextAlignment(.trailing)
  51. }
  52. HStack {
  53. Text("Password")
  54. TogglableSecureInput(
  55. placeholder: "Enter Password",
  56. text: $viewModel.password,
  57. style: .singleLine,
  58. textContentType: .password
  59. )
  60. }
  61. Picker("Server", selection: $viewModel.server) {
  62. Text("US").tag("US")
  63. Text("Outside US").tag("NON-US")
  64. }
  65. .pickerStyle(.segmented)
  66. }
  67. }
  68. }
  69. // MARK: - Status pill mapping
  70. private var statusColor: Color {
  71. switch viewModel.statusKind {
  72. case .idle: return .secondary
  73. case .checking: return .orange
  74. case .connected: return .green
  75. case .error: return .red
  76. }
  77. }
  78. private var statusIcon: String? {
  79. switch viewModel.statusKind {
  80. case .idle: return "circle"
  81. case .checking: return nil
  82. case .connected: return "checkmark.circle.fill"
  83. case .error: return "exclamationmark.triangle.fill"
  84. }
  85. }
  86. }