Files
swift-estimated-pressures-core/Sources/PressureEstimationsFeature/PressureEstimations.swift

141 lines
3.7 KiB
Swift

import ComposableArchitecture
import DependenciesAdditions
import SharedModels
import Styleguide
import SwiftUI
import TCAExtras
#warning("Fix shared settings.")
@Reducer
public struct PressureEstimationsFeature {
public init() { }
@Reducer(state: .equatable)
public enum Destination {
case equipmentMeasurements(EquipmentMeasurementForm)
}
@ObservableState
public struct State: Equatable {
@Presents public var destination: Destination.State?
@Shared(.sharedPressureEstimationSettings) var sharedSettings = SharedPressureEstimationState()
public var equipmentSettings: EquipmentSettingsForm.State
public init(
destination: Destination.State? = nil,
sharedSettings: SharedPressureEstimationState = .init()
) {
self.destination = destination
self._sharedSettings = Shared(sharedSettings)
self._equipmentSettings = .init(sharedSettings: self._sharedSettings)
}
}
public enum Action: ViewAction {
case destination(PresentationAction<Destination.Action>)
case equipmentSettings(EquipmentSettingsForm.Action)
case view(View)
@CasePathable
public enum View {
case nextButtonTapped
}
}
@Dependency(\.logger["\(Self.self)"]) var logger
public var body: some Reducer<State, Action> {
Scope(state: \.equipmentSettings, action: \.equipmentSettings) {
EquipmentSettingsForm()
}
Reduce<State, Action> { state, action in
switch action {
case .destination:
return .none
case .equipmentSettings:
return .none
case let .view(action):
switch action {
case .nextButtonTapped:
return handleNextButtonTapped(&state)
}
}
}
.ifLet(\.$destination, action: \.destination)
}
private func handleNextButtonTapped(_ state: inout State) -> Effect<Action> {
guard state.destination == nil else {
return .fail(
"""
Received next button tapped action on equipment settings form, but the destination is not nil.
This is considered an application logic error.
""",
logger: logger
)
}
guard state.equipmentSettings.isValid else {
return .fail(
"""
Received next button tapped action on equipment settings form, but the form is invalid.
This is considered an application logic error.
""",
logger: logger
)
}
state.destination = .equipmentMeasurements(.init(
allowEquipmentTypeSelection: false,
sharedSettings: state.$sharedSettings,
equipmentType: state.equipmentSettings.equipmentType
))
return .none
}
}
@ViewAction(for: PressureEstimationsFeature.self)
public struct PressureEstimationsView: View {
@Bindable public var store: StoreOf<PressureEstimationsFeature>
public init(store: StoreOf<PressureEstimationsFeature>) {
self.store = store
}
public var body: some View {
EquipmentSettingsFormView(
store: store.scope(state: \.equipmentSettings, action: \.equipmentSettings)
)
.navigationTitle("Equipment Settings")
.toolbar {
NextButton { send(.nextButtonTapped) }
.nextButtonStyle(.toolbar)
.disabled(!store.equipmentSettings.isValid)
}
.navigationDestination(
item: $store.scope(
state: \.destination?.equipmentMeasurements,
action: \.destination.equipmentMeasurements
)
) { measurementStore in
EquipmentMeasurementFormView(store: measurementStore)
.navigationTitle("Existing Measurements")
}
}
}
#Preview {
NavigationStack {
PressureEstimationsView(
store: Store(initialState: PressureEstimationsFeature.State()) {
PressureEstimationsFeature()._printChanges()
}
)
}
}