import ComposableArchitecture import DependenciesAdditions import EstimatedPressureDependency import SharedModels import SwiftUI import TCAExtras @Reducer public struct AirHandlerMeasurementForm { @ObservableState public struct State: Equatable { public var calculatedMeasurement: EquipmentMeasurement.AirHandler? public var focusedField: Field? public var measurement: EquipmentMeasurement.AirHandler public var updatedAirflow: Double? public init( calculatedMeasurement: EquipmentMeasurement.AirHandler? = nil, focusedField: Field? = nil, measurement: EquipmentMeasurement.AirHandler = .init(), updatedAirflow: Double? = nil ) { self.calculatedMeasurement = calculatedMeasurement self.focusedField = focusedField self.measurement = measurement self.updatedAirflow = updatedAirflow } public var isValid: Bool { return measurement.returnPlenumPressure != nil && measurement.postFilterPressure != nil && measurement.postCoilPressure != nil && measurement.supplyPlenumPressure != nil && measurement.airflow != nil && updatedAirflow != nil } public enum Field: String, Equatable, CaseIterable, FocusableField { case returnPlenumPressure case postFilterPressure case postCoilPressure case supplyPlenumPressure case airflow } } public enum Action: BindableAction, ViewAction { case binding(BindingAction) case receive(TaskResult) case view(View) @CasePathable public enum View { case submitField } } @Dependency(\.estimatedPressuresClient) var estimatedPressuresClient @Dependency(\.logger["\(Self.self)"]) var logger public var body: some Reducer { BindingReducer() Reduce { state, action in switch action { case .binding: return .none case let .receive(.success(calculatedMeasurement)): state.calculatedMeasurement = calculatedMeasurement return .none case .receive: return .none case let .view(action): switch action { case .submitField: state.focusedField = state.focusedField?.next guard state.isValid else { return .none } return calculateEstimates(state: state) } } } .onFailure(case: \.receive, .log(logger: logger)) } private func calculateEstimates(state: State) -> Effect { .receive(action: \.receive) { let result = try await estimatedPressuresClient.estimatedPressure( for: .airHandler(state.measurement), at: state.updatedAirflow ?? 0 ) guard case let .airHandler(airHandler) = result else { return .none } return airHandler } // return .receive(action: \.recieve) { // try await estimatedPressuresClient.estimatedM // } } } public struct EquipmentMeasurementFormView: View { public var body: some View { Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) } } #Preview { EquipmentMeasurementFormView() }