From 4d6a5d3f06f7f484049e52f41f519ff678b916c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=A9=E1=86=BC=E1=84=8B=E1=85=A7=E1=86=BC?= =?UTF-8?q?=E1=84=86=E1=85=A9?= Date: Sun, 18 Jun 2023 21:50:03 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20workout=20end=20view=20=EB=94=94?= =?UTF-8?q?=ED=85=8C=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../End/WorkoutEndStoreInterface.swift | 13 ++ .../Sources/End/WorkoutEndView.swift | 176 +++++++++--------- .../Workout/Sources/WorkoutEndStore.swift | 3 + .../Workout/Sources/WorkoutRootStore.swift | 6 +- 4 files changed, 110 insertions(+), 88 deletions(-) diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift index 31d6d6f..a1a05e7 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift @@ -6,8 +6,11 @@ // import Foundation + import ComposableArchitecture +import SharedDesignSystem + public struct WorkoutEndStore: ReducerProtocol { private let reducer: Reduce @@ -16,6 +19,13 @@ public struct WorkoutEndStore: ReducerProtocol { } public struct State: Equatable { + public var workoutTime: Int = 10000 + public var workoutCalorie: Int = 300 + public var workoutToolCells: IdentifiedArrayOf = [ + .init(id: .init(), title: "어깨"), + .init(id: .init(), title: "등") + ] + public init() { } @@ -26,6 +36,9 @@ public struct WorkoutEndStore: ReducerProtocol { case completeButtonTapped + case pumpingTextCell(id: PumpingTextCellStore.State.ID, action: PumpingTextCellStore.Action) + + //MARK: Navigation case backToRoot } diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift index 2dd1ea8..c30464c 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift @@ -10,6 +10,7 @@ import SwiftUI import ComposableArchitecture import SharedDesignSystem +import SharedUtil public struct WorkoutEndView: View { public let store: StoreOf @@ -21,101 +22,104 @@ public struct WorkoutEndView: View { public var body: some View { WithViewStore(self.store, observe: { $0 }) { viewStore in VStack { - VStack { - HStack { - Text("운동을 모두 끝냈어요!") - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(SharedDesignSystemAsset.Colors.colorGrey100.swiftUIColor) - - Spacer() - } - .padding(.horizontal) - - HStack { - Text("오늘 한 운동 세트를 기록할 수 있어요") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(.colorGrey000) - - Spacer() - } - .padding(.horizontal) - - SharedDesignSystemAsset.Images.boy.swiftUIImage - } - .background(Color.colorCyan300) + titleView() - HStack { - HStack { - Spacer() - - VStack(spacing: 4) { - Text("오늘 운동 시간") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(.colorCyan300) - - Text("01:00:00") - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(.colorGrey900) - } - - Spacer() - - VStack(spacing: 4) { - Text("소모 칼로리") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(.colorCyan300) - - Text("300kcal") - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(.colorGrey900) - } - - Spacer() - } - .frame(maxWidth: .infinity) - .padding() - .background(Color.colorGrey100) - .cornerRadius(12) + resultView(viewStore: viewStore) .offset(.init(width: 0, height: -40)) - - } - .padding() + .padding(.horizontal) - HStack { - Text("오늘 한 운동") - .font(.pretendard(size: 18, type: .bold)) - .foregroundColor(Color.colorGrey900) - - Spacer() - - Text("세트 기록") - .font(.pretendard(size: 16, type: .bold)) - .foregroundColor(Color.colorGrey600) - - Image(systemName: "highlighter") - .imageScale(.medium) - .foregroundColor(.colorCyan300) - - //TODO: TextCellView Merge 후 작업 예정 - } - .padding(.horizontal) + workoutToolListView(viewStore: viewStore) Spacer() - Button(action: { + PumpingSubmitButton(title: "완료", completion: { viewStore.send(.completeButtonTapped) - }, label: { - Text("완료") - .font(.pretendard(size: 18, type: .bold)) - .foregroundColor(.colorGrey000) - .frame(maxWidth: .infinity) - .frame(height: 52) }) - .background(Color.colorCyan300) - .cornerRadius(12) - .padding(.horizontal) - .padding(.bottom, 34) + .padding() + } + .navigationBarBackButtonHidden(true) + } + } + + @ViewBuilder + private func titleView() -> some View { + VStack(alignment: .leading, spacing: 12) { + Text("운동을 모두 끝냈어요!") + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(PumpingColors.colorGrey100.swiftUIColor) + + Text("오늘 한 운동 세트를 기록할 수 있어요") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(PumpingColors.colorGrey000.swiftUIColor) + + SharedDesignSystemAsset.Images.boy.swiftUIImage + + HStack { + Spacer() + } + } + .padding(.horizontal) + .background(Color.colorCyan300) + } + + @ViewBuilder + private func resultView(viewStore: ViewStoreOf) -> some View { + HStack { + Spacer() + + VStack(spacing: 4) { + Text("오늘 운동 시간") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(.colorCyan300) + + Text(DateManager.toClockString(from: viewStore.state.workoutTime)) + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(.colorGrey900) + } + + Spacer() + + VStack(spacing: 4) { + Text("소모 칼로리") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(.colorCyan300) + + Text("\(viewStore.state.workoutCalorie)kcal") + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(.colorGrey900) + } + + Spacer() + } + .frame(maxWidth: .infinity) + .padding() + .background(Color.colorGrey100) + .cornerRadius(12) + } + + @ViewBuilder + private func workoutToolListView(viewStore: ViewStoreOf) -> some View { + VStack { + HStack { + Text("오늘 한 운동 기구") + .font(.pretendard(size: 18, type: .bold)) + .foregroundColor(Color.colorGrey900) + + Spacer() + + Text("세트 기록") + .font(.pretendard(size: 16, type: .bold)) + .foregroundColor(Color.colorGrey600) + + Image(systemName: "highlighter") + .imageScale(.medium) + .foregroundColor(.colorCyan300) + } + + ForEachStore(self.store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { + PumpingTextCellView(store: $0) } } + .padding(.horizontal) } } diff --git a/Projects/Feature/Workout/Sources/WorkoutEndStore.swift b/Projects/Feature/Workout/Sources/WorkoutEndStore.swift index 32b4882..bd61625 100644 --- a/Projects/Feature/Workout/Sources/WorkoutEndStore.swift +++ b/Projects/Feature/Workout/Sources/WorkoutEndStore.swift @@ -20,6 +20,9 @@ extension WorkoutEndStore { case .completeButtonTapped: return .send(.backToRoot) + case let .pumpingTextCell(id, action): + return .none + case .backToRoot: return .none } diff --git a/Projects/Feature/Workout/Sources/WorkoutRootStore.swift b/Projects/Feature/Workout/Sources/WorkoutRootStore.swift index cae2c6b..db7ca31 100644 --- a/Projects/Feature/Workout/Sources/WorkoutRootStore.swift +++ b/Projects/Feature/Workout/Sources/WorkoutRootStore.swift @@ -18,8 +18,10 @@ extension WorkoutRootStore { return .none case .startButtonTapped: - state.workoutHome = .init() - state.path.append(.selectWorkoutCategoryType) +// state.workoutHome = .init() +// state.path.append(.selectWorkoutCategoryType) + state.workoutEnd = .init() + state.path.append(.workoutEnd) return .none case let .workoutHome(action): From 50c4ce8601acab3b982ac9b3cf38f587c74280c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=A9=E1=86=BC=E1=84=8B=E1=85=A7=E1=86=BC?= =?UTF-8?q?=E1=84=86=E1=85=A9?= Date: Sun, 18 Jun 2023 21:51:37 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20divider=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Workout/Interface/Sources/End/WorkoutEndView.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift index c30464c..e067c25 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift @@ -79,6 +79,11 @@ public struct WorkoutEndView: View { Spacer() + Divider() + .frame(height: 54) + + Spacer() + VStack(spacing: 4) { Text("소모 칼로리") .font(.pretendard(size: 15, type: .medium)) From e4e374be2e5352c980a824e1a2b9897f65f47773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=A9=E1=86=BC=E1=84=8B=E1=85=A7=E1=86=BC?= =?UTF-8?q?=E1=84=86=E1=85=A9?= Date: Mon, 19 Jun 2023 10:38:42 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WorkoutCounterStoreInterface.swift | 1 - .../End/WorkoutEndStoreInterface.swift | 2 + .../Sources/End/WorkoutEndView.swift | 10 +++- .../Record/WorkoutRecordStoreInterface.swift | 40 +++++++++++++ .../Sources/Record/WorkoutRecordView.swift | 56 +++++++++++++++++++ .../Root/WorkoutRootStoreInterface.swift | 19 +++++-- .../Sources/Root/WorkoutRootView.swift | 13 +++-- .../{ => Counter}/WorkoutCounterStore.swift | 0 .../Sources/{ => End}/WorkoutEndStore.swift | 6 ++ .../Sources/{ => Home}/WorkoutHomeStore.swift | 0 .../Sources/Record/WorkoutRecordStore.swift | 33 +++++++++++ .../Sources/{ => Root}/WorkoutRootStore.swift | 19 +++++-- .../{ => Start}/WorkoutStartStore.swift | 0 .../{ => Timer}/WorkoutTimerStore.swift | 0 .../Cells/WorkoutRecordCellStore.swift | 38 +++++++++++++ .../Sources/Cells/WorkoutRecordCellView.swift | 49 ++++++++++++++++ 16 files changed, 268 insertions(+), 18 deletions(-) create mode 100644 Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordStoreInterface.swift create mode 100644 Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordView.swift rename Projects/Feature/Workout/Sources/{ => Counter}/WorkoutCounterStore.swift (100%) rename Projects/Feature/Workout/Sources/{ => End}/WorkoutEndStore.swift (80%) rename Projects/Feature/Workout/Sources/{ => Home}/WorkoutHomeStore.swift (100%) create mode 100644 Projects/Feature/Workout/Sources/Record/WorkoutRecordStore.swift rename Projects/Feature/Workout/Sources/{ => Root}/WorkoutRootStore.swift (79%) rename Projects/Feature/Workout/Sources/{ => Start}/WorkoutStartStore.swift (100%) rename Projects/Feature/Workout/Sources/{ => Timer}/WorkoutTimerStore.swift (100%) create mode 100644 Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellStore.swift create mode 100644 Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellView.swift diff --git a/Projects/Feature/Workout/Interface/Sources/Counter/WorkoutCounterStoreInterface.swift b/Projects/Feature/Workout/Interface/Sources/Counter/WorkoutCounterStoreInterface.swift index 4dccb9b..fedd8db 100644 --- a/Projects/Feature/Workout/Interface/Sources/Counter/WorkoutCounterStoreInterface.swift +++ b/Projects/Feature/Workout/Interface/Sources/Counter/WorkoutCounterStoreInterface.swift @@ -7,7 +7,6 @@ import SwiftUI -import Foundation import ComposableArchitecture import SharedDesignSystem diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift index a1a05e7..72d0ef0 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndStoreInterface.swift @@ -34,12 +34,14 @@ public struct WorkoutEndStore: ReducerProtocol { public enum Action: BindableAction, Equatable { case binding(BindingAction) + case editButtonTapped case completeButtonTapped case pumpingTextCell(id: PumpingTextCellStore.State.ID, action: PumpingTextCellStore.Action) //MARK: Navigation case backToRoot + case goToWorkoutRecord } public var body: some ReducerProtocol { diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift index e067c25..46ebb50 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift @@ -116,9 +116,13 @@ public struct WorkoutEndView: View { .font(.pretendard(size: 16, type: .bold)) .foregroundColor(Color.colorGrey600) - Image(systemName: "highlighter") - .imageScale(.medium) - .foregroundColor(.colorCyan300) + Button(action: { + viewStore.send(.editButtonTapped) + }, label: { + Image(systemName: "highlighter") + .imageScale(.medium) + .foregroundColor(.colorCyan300) + }) } ForEachStore(self.store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { diff --git a/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordStoreInterface.swift b/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordStoreInterface.swift new file mode 100644 index 0000000..bfa0cb0 --- /dev/null +++ b/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordStoreInterface.swift @@ -0,0 +1,40 @@ +// +// WorkoutRecordStoreInterface.swift +// FeatureWorkoutInterface +// +// Created by 송영모 on 2023/06/18. +// + +import SwiftUI + +import ComposableArchitecture + +import SharedDesignSystem +import DomainAuth + +public struct WorkoutRecordStore: ReducerProtocol { + private let reducer: Reduce + + public init(reducer: Reduce) { + self.reducer = reducer + } + + public struct State: Equatable { + public init() { + + } + } + + public enum Action: BindableAction, Equatable { + case binding(BindingAction) + + case onAppear + + case completeButtonTapped + } + + public var body: some ReducerProtocol { + BindingReducer() + reducer + } +} diff --git a/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordView.swift b/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordView.swift new file mode 100644 index 0000000..da6a138 --- /dev/null +++ b/Projects/Feature/Workout/Interface/Sources/Record/WorkoutRecordView.swift @@ -0,0 +1,56 @@ +// +// WorkoutRecordView.swift +// FeatureWorkoutInterface +// +// Created by 송영모 on 2023/06/18. +// + +import SwiftUI + +import ComposableArchitecture + +import SharedDesignSystem + +public struct WorkoutRecordView: View { + public let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + WithViewStore(self.store, observe: { $0 }) { viewStore in + VStack { + titleView() + .padding(.horizontal) + + Spacer() + + PumpingSubmitButton(title: "완료", completion: { + viewStore.send(.completeButtonTapped) + }) + } + .navigationBarBackButtonHidden(true) + .onAppear { + viewStore.send(.onAppear) + } + } + } + + @ViewBuilder + private func titleView() -> some View { + VStack(alignment: .leading, spacing: 12) { + Text("오늘 수행한 세트를 알려주세요.") + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(PumpingColors.colorGrey900.swiftUIColor) + + Text("운동 기구와 중량도 작성할 수 있어요.") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(.colorGrey600) + + HStack { + Spacer() + } + } + } +} diff --git a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootStoreInterface.swift b/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootStoreInterface.swift index b620ab9..73c6ae3 100644 --- a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootStoreInterface.swift +++ b/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootStoreInterface.swift @@ -9,10 +9,11 @@ import ComposableArchitecture public enum WorkoutScene: Hashable { case root - case selectWorkoutCategoryType - case workoutStart - case workoutTimer - case workoutEnd + case home + case start + case timer + case end + case record } public struct WorkoutRootStore: ReducerProtocol { @@ -22,13 +23,15 @@ public struct WorkoutRootStore: ReducerProtocol { private let workoutStartStore: WorkoutStartStore private let workoutTimerStore: WorkoutTimerStore private let workoutEndStore: WorkoutEndStore + private let workoutRecordStore: WorkoutRecordStore public init( reducer: Reduce, workoutHomeStore: WorkoutHomeStore, workoutStartStore: WorkoutStartStore, workoutTimerStore: WorkoutTimerStore, - workoutEndStore: WorkoutEndStore + workoutEndStore: WorkoutEndStore, + workoutRecordStore: WorkoutRecordStore ) { self.reducer = reducer @@ -36,6 +39,7 @@ public struct WorkoutRootStore: ReducerProtocol { self.workoutStartStore = workoutStartStore self.workoutTimerStore = workoutTimerStore self.workoutEndStore = workoutEndStore + self.workoutRecordStore = workoutRecordStore } public struct State: Equatable { @@ -45,6 +49,7 @@ public struct WorkoutRootStore: ReducerProtocol { public var workoutStart: WorkoutStartStore.State? public var workoutTimer: WorkoutTimerStore.State? public var workoutEnd: WorkoutEndStore.State? + public var workoutRecord: WorkoutRecordStore.State? public init() { @@ -60,6 +65,7 @@ public struct WorkoutRootStore: ReducerProtocol { case workoutStart(WorkoutStartStore.Action) case workoutTimer(WorkoutTimerStore.Action) case workoutEnd(WorkoutEndStore.Action) + case workoutRecord(WorkoutRecordStore.Action) } public var body: some ReducerProtocol { @@ -77,5 +83,8 @@ public struct WorkoutRootStore: ReducerProtocol { .ifLet(\.workoutEnd, action: /Action.workoutEnd) { workoutEndStore } + .ifLet(\.workoutRecord, action: /Action.workoutRecord) { + workoutRecordStore + } } } diff --git a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift b/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift index 42b3696..67f02c8 100644 --- a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift +++ b/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift @@ -56,26 +56,31 @@ public struct WorkoutRootView: View { .background(Color.colorGrey000) .navigationDestination(for: WorkoutScene.self) { scene in switch scene { - case .selectWorkoutCategoryType: + case .home: IfLetStore(self.store.scope(state: \.workoutHome, action: { .workoutHome($0) })) { WorkoutHomeView(store: $0) } - case .workoutStart: + case .start: IfLetStore(self.store.scope(state: \.workoutStart, action: { .workoutStart($0) })) { WorkoutStartView(store: $0) } - case .workoutTimer: + case .timer: IfLetStore(self.store.scope(state: \.workoutTimer, action: { .workoutTimer($0) })) { WorkoutTimerView(store: $0) } - case .workoutEnd: + case .end: IfLetStore(self.store.scope(state: \.workoutEnd, action: { .workoutEnd($0) })) { WorkoutEndView(store: $0) } + case .record: + IfLetStore(self.store.scope(state: \.workoutRecord, action: { .workoutRecord($0) })) { + WorkoutRecordView(store: $0) + } + default: EmptyView() } diff --git a/Projects/Feature/Workout/Sources/WorkoutCounterStore.swift b/Projects/Feature/Workout/Sources/Counter/WorkoutCounterStore.swift similarity index 100% rename from Projects/Feature/Workout/Sources/WorkoutCounterStore.swift rename to Projects/Feature/Workout/Sources/Counter/WorkoutCounterStore.swift diff --git a/Projects/Feature/Workout/Sources/WorkoutEndStore.swift b/Projects/Feature/Workout/Sources/End/WorkoutEndStore.swift similarity index 80% rename from Projects/Feature/Workout/Sources/WorkoutEndStore.swift rename to Projects/Feature/Workout/Sources/End/WorkoutEndStore.swift index bd61625..6cef15d 100644 --- a/Projects/Feature/Workout/Sources/WorkoutEndStore.swift +++ b/Projects/Feature/Workout/Sources/End/WorkoutEndStore.swift @@ -17,12 +17,18 @@ extension WorkoutEndStore { case .binding: return .none + case .editButtonTapped: + return .send(.goToWorkoutRecord) + case .completeButtonTapped: return .send(.backToRoot) case let .pumpingTextCell(id, action): return .none + case .goToWorkoutRecord: + return .none + case .backToRoot: return .none } diff --git a/Projects/Feature/Workout/Sources/WorkoutHomeStore.swift b/Projects/Feature/Workout/Sources/Home/WorkoutHomeStore.swift similarity index 100% rename from Projects/Feature/Workout/Sources/WorkoutHomeStore.swift rename to Projects/Feature/Workout/Sources/Home/WorkoutHomeStore.swift diff --git a/Projects/Feature/Workout/Sources/Record/WorkoutRecordStore.swift b/Projects/Feature/Workout/Sources/Record/WorkoutRecordStore.swift new file mode 100644 index 0000000..c706203 --- /dev/null +++ b/Projects/Feature/Workout/Sources/Record/WorkoutRecordStore.swift @@ -0,0 +1,33 @@ +// +// WorkoutRecordStore.swift +// FeatureWorkoutInterface +// +// Created by 송영모 on 2023/06/19. +// + +import Foundation + +import ComposableArchitecture + +import FeatureWorkoutInterface + +extension WorkoutRecordStore { + public init() { + let reducer: Reduce = .init { state, action in + switch action { + case .binding: + return .none + + case .onAppear: + return .none + + case .completeButtonTapped: + return .none + } + } + + self.init( + reducer: reducer + ) + } +} diff --git a/Projects/Feature/Workout/Sources/WorkoutRootStore.swift b/Projects/Feature/Workout/Sources/Root/WorkoutRootStore.swift similarity index 79% rename from Projects/Feature/Workout/Sources/WorkoutRootStore.swift rename to Projects/Feature/Workout/Sources/Root/WorkoutRootStore.swift index db7ca31..80aff85 100644 --- a/Projects/Feature/Workout/Sources/WorkoutRootStore.swift +++ b/Projects/Feature/Workout/Sources/Root/WorkoutRootStore.swift @@ -21,14 +21,14 @@ extension WorkoutRootStore { // state.workoutHome = .init() // state.path.append(.selectWorkoutCategoryType) state.workoutEnd = .init() - state.path.append(.workoutEnd) + state.path.append(.end) return .none case let .workoutHome(action): switch action { case .goToWorkoutStart: state.workoutStart = .init() - state.path.append(.workoutStart) + state.path.append(.start) return .none default: @@ -38,7 +38,7 @@ extension WorkoutRootStore { switch action { case .goToWorkoutTimer: state.workoutTimer = .init(workoutCategoryIdentifiers: [.back, .aerobic, .butt]) - state.path.append(.workoutTimer) + state.path.append(.timer) return .none default: @@ -49,7 +49,7 @@ extension WorkoutRootStore { switch action { case .goToWorkoutEnd: state.workoutEnd = .init() - state.path.append(.workoutEnd) + state.path.append(.end) return .none default: @@ -61,9 +61,17 @@ extension WorkoutRootStore { state.path = [] return .none + case .goToWorkoutRecord: + state.workoutRecord = .init() + state.path.append(.record) + return .none + default: return .none } + + case let .workoutRecord(action): + return .none } } @@ -72,7 +80,8 @@ extension WorkoutRootStore { workoutHomeStore: .init(), workoutStartStore: .init(), workoutTimerStore: .init(), - workoutEndStore: .init() + workoutEndStore: .init(), + workoutRecordStore: .init() ) } } diff --git a/Projects/Feature/Workout/Sources/WorkoutStartStore.swift b/Projects/Feature/Workout/Sources/Start/WorkoutStartStore.swift similarity index 100% rename from Projects/Feature/Workout/Sources/WorkoutStartStore.swift rename to Projects/Feature/Workout/Sources/Start/WorkoutStartStore.swift diff --git a/Projects/Feature/Workout/Sources/WorkoutTimerStore.swift b/Projects/Feature/Workout/Sources/Timer/WorkoutTimerStore.swift similarity index 100% rename from Projects/Feature/Workout/Sources/WorkoutTimerStore.swift rename to Projects/Feature/Workout/Sources/Timer/WorkoutTimerStore.swift diff --git a/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellStore.swift b/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellStore.swift new file mode 100644 index 0000000..b6598a7 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellStore.swift @@ -0,0 +1,38 @@ +// +// WorkoutRecordCellStore.swift +// SharedDesignSystem +// +// Created by 송영모 on 2023/06/19. +// + +import Foundation + +import ComposableArchitecture + +public struct WorkoutRecordCellStore: ReducerProtocol { + public init() { } + + public struct State: Equatable, Identifiable { + public let id: UUID + public let title: String + + public var isTapped: Bool + + public init(id: UUID, title: String, isTapped: Bool = false) { + self.id = id + self.title = title + self.isTapped = isTapped + } + } + + public enum Action: Equatable { + case tapped + } + + public func reduce(into state: inout State, action: Action) -> EffectTask { + switch action { + case .tapped: + return .none + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellView.swift b/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellView.swift new file mode 100644 index 0000000..ab18b0a --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Cells/WorkoutRecordCellView.swift @@ -0,0 +1,49 @@ +// +// WorkoutRecordCellView.swift +// SharedDesignSystem +// +// Created by 송영모 on 2023/06/19. +// + +import SwiftUI + +import ComposableArchitecture + +public struct WorkoutRecordCellView: View { + public let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + WithViewStore(self.store, observe: { $0 }) { viewStore in + HStack { + Text(viewStore.state.title) + .font(.pretendard(size: 15, type: .medium)) + .padding([.top, .bottom], 16) + .padding(.leading, 20) + + Spacer() + + if viewStore.isTapped { + PumpingImages.active.swiftUIImage + .resizable() + .frame(width: 28, height: 28) + .padding(.trailing, 17) + } + } + .contentShape(Rectangle()) + .onTapGesture { + viewStore.send(.tapped) + } + .background(viewStore.isTapped ? PumpingColors.colorCyan100.swiftUIColor : .clear) + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(viewStore.isTapped ? PumpingColors.colorCyan200.swiftUIColor : PumpingColors.colorGrey300.swiftUIColor, lineWidth: 1) + ) + } + } +} + From 441e959bc5afc559f33b045d5fedc3a92f7a26f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=A9=E1=86=BC=E1=84=8B=E1=85=A7=E1=86=BC?= =?UTF-8?q?=E1=84=86=E1=85=A9?= Date: Thu, 22 Jun 2023 13:03:01 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20di=20container=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/End/WorkoutEndView.swift | 243 +++++++++--------- .../Sources/End/WorkoutEndViewInterface.swift | 27 ++ .../Sources/End/WorkoutEndDIContainer.swift | 24 ++ .../Workout/Sources/End/WorkoutEndView.swift | 134 ++++++++++ .../WorkoutRootCompositionDIContainer.swift | 8 + .../Sources/Root/WorkoutRootView.swift | 24 +- 6 files changed, 331 insertions(+), 129 deletions(-) create mode 100644 Projects/Feature/Workout/Interface/Sources/End/WorkoutEndViewInterface.swift create mode 100644 Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift create mode 100644 Projects/Feature/Workout/Sources/End/WorkoutEndView.swift create mode 100644 Projects/Feature/Workout/Sources/Root/WorkoutRootCompositionDIContainer.swift rename Projects/Feature/Workout/{Interface => }/Sources/Root/WorkoutRootView.swift (79%) diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift index 46ebb50..de91ef5 100644 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift @@ -12,123 +12,126 @@ import ComposableArchitecture import SharedDesignSystem import SharedUtil -public struct WorkoutEndView: View { - public let store: StoreOf - - public init(store: StoreOf) { - self.store = store - } - - public var body: some View { - WithViewStore(self.store, observe: { $0 }) { viewStore in - VStack { - titleView() - - resultView(viewStore: viewStore) - .offset(.init(width: 0, height: -40)) - .padding(.horizontal) - - workoutToolListView(viewStore: viewStore) - - Spacer() - - PumpingSubmitButton(title: "완료", completion: { - viewStore.send(.completeButtonTapped) - }) - .padding() - } - .navigationBarBackButtonHidden(true) - } - } - - @ViewBuilder - private func titleView() -> some View { - VStack(alignment: .leading, spacing: 12) { - Text("운동을 모두 끝냈어요!") - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(PumpingColors.colorGrey100.swiftUIColor) - - Text("오늘 한 운동 세트를 기록할 수 있어요") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(PumpingColors.colorGrey000.swiftUIColor) - - SharedDesignSystemAsset.Images.boy.swiftUIImage - - HStack { - Spacer() - } - } - .padding(.horizontal) - .background(Color.colorCyan300) - } - - @ViewBuilder - private func resultView(viewStore: ViewStoreOf) -> some View { - HStack { - Spacer() - - VStack(spacing: 4) { - Text("오늘 운동 시간") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(.colorCyan300) - - Text(DateManager.toClockString(from: viewStore.state.workoutTime)) - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(.colorGrey900) - } - - Spacer() - - Divider() - .frame(height: 54) - - Spacer() - - VStack(spacing: 4) { - Text("소모 칼로리") - .font(.pretendard(size: 15, type: .medium)) - .foregroundColor(.colorCyan300) - - Text("\(viewStore.state.workoutCalorie)kcal") - .font(.pretendard(size: 24, type: .bold)) - .foregroundColor(.colorGrey900) - } - - Spacer() - } - .frame(maxWidth: .infinity) - .padding() - .background(Color.colorGrey100) - .cornerRadius(12) - } - - @ViewBuilder - private func workoutToolListView(viewStore: ViewStoreOf) -> some View { - VStack { - HStack { - Text("오늘 한 운동 기구") - .font(.pretendard(size: 18, type: .bold)) - .foregroundColor(Color.colorGrey900) - - Spacer() - - Text("세트 기록") - .font(.pretendard(size: 16, type: .bold)) - .foregroundColor(Color.colorGrey600) - - Button(action: { - viewStore.send(.editButtonTapped) - }, label: { - Image(systemName: "highlighter") - .imageScale(.medium) - .foregroundColor(.colorCyan300) - }) - } - - ForEachStore(self.store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { - PumpingTextCellView(store: $0) - } - } - .padding(.horizontal) - } -} +//public struct WorkoutEndView: View { +// private let store: StoreOf +// private let content: () -> Content +// +// public init(store: StoreOf, content: @escaping () -> Content) { +// self.store = store +// self.content = content +// } +// +// public var body: some View { +// content() +// WithViewStore(self.store, observe: { $0 }) { viewStore in +// VStack { +// titleView() +// +// resultView(viewStore: viewStore) +// .offset(.init(width: 0, height: -40)) +// .padding(.horizontal) +// +// workoutToolListView(viewStore: viewStore) +// +// Spacer() +// +// PumpingSubmitButton(title: "완료", completion: { +// viewStore.send(.completeButtonTapped) +// }) +// .padding() +// } +// .navigationBarBackButtonHidden(true) +// } +// } +// +// @ViewBuilder +// private func titleView() -> some View { +// VStack(alignment: .leading, spacing: 12) { +// Text("운동을 모두 끝냈어요!") +// .font(.pretendard(size: 24, type: .bold)) +// .foregroundColor(PumpingColors.colorGrey100.swiftUIColor) +// +// Text("오늘 한 운동 세트를 기록할 수 있어요") +// .font(.pretendard(size: 15, type: .medium)) +// .foregroundColor(PumpingColors.colorGrey000.swiftUIColor) +// +// SharedDesignSystemAsset.Images.boy.swiftUIImage +// +// HStack { +// Spacer() +// } +// } +// .padding(.horizontal) +// .background(Color.colorCyan300) +// } +// +// @ViewBuilder +// private func resultView(viewStore: ViewStoreOf) -> some View { +// HStack { +// Spacer() +// +// VStack(spacing: 4) { +// Text("오늘 운동 시간") +// .font(.pretendard(size: 15, type: .medium)) +// .foregroundColor(.colorCyan300) +// +// Text(DateManager.toClockString(from: viewStore.state.workoutTime)) +// .font(.pretendard(size: 24, type: .bold)) +// .foregroundColor(.colorGrey900) +// } +// +// Spacer() +// +// Divider() +// .frame(height: 54) +// +// Spacer() +// +// VStack(spacing: 4) { +// Text("소모 칼로리") +// .font(.pretendard(size: 15, type: .medium)) +// .foregroundColor(.colorCyan300) +// +// Text("\(viewStore.state.workoutCalorie)kcal") +// .font(.pretendard(size: 24, type: .bold)) +// .foregroundColor(.colorGrey900) +// } +// +// Spacer() +// } +// .frame(maxWidth: .infinity) +// .padding() +// .background(Color.colorGrey100) +// .cornerRadius(12) +// } +// +// @ViewBuilder +// private func workoutToolListView(viewStore: ViewStoreOf) -> some View { +// VStack { +// HStack { +// Text("오늘 한 운동 기구") +// .font(.pretendard(size: 18, type: .bold)) +// .foregroundColor(Color.colorGrey900) +// +// Spacer() +// +// Text("세트 기록") +// .font(.pretendard(size: 16, type: .bold)) +// .foregroundColor(Color.colorGrey600) +// +// Button(action: { +// viewStore.send(.editButtonTapped) +// }, label: { +// Image(systemName: "highlighter") +// .imageScale(.medium) +// .foregroundColor(.colorCyan300) +// }) +// } +// +// ForEachStore(self.store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { +// PumpingTextCellView(store: $0) +// } +// } +// .padding(.horizontal) +// } +//} diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndViewInterface.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndViewInterface.swift new file mode 100644 index 0000000..09917cc --- /dev/null +++ b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndViewInterface.swift @@ -0,0 +1,27 @@ +// +// WorkoutEndViewInterface.swift +// FeatureWorkoutInterface +// +// Created by 송영모 on 2023/06/21. +// + +import SwiftUI + +import ComposableArchitecture + +import SharedDesignSystem +import SharedUtil + +public struct WorkoutEndView: View { + private let store: StoreOf + public var content: () -> Content + + public init(store: StoreOf, @ViewBuilder content: @escaping () -> Content) { + self.store = store + self.content = content + } + + public var body: some View { + content() + } +} diff --git a/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift b/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift new file mode 100644 index 0000000..b77b0ef --- /dev/null +++ b/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift @@ -0,0 +1,24 @@ +// +// WorkoutEndDIContainer.swift +// FeatureWorkout +// +// Created by 송영모 on 2023/06/21. +// + +import SwiftUI + +import ComposableArchitecture + +import FeatureWorkoutInterface + +class WorkoutEndDIContainer { + static let shared = WorkoutEndDIContainer() + + private init() {} + + func resolve(store: StoreOf) -> WorkoutEndView { + return .init() { + self.makeView(store: store) + } + } +} diff --git a/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift new file mode 100644 index 0000000..cacdfd4 --- /dev/null +++ b/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift @@ -0,0 +1,134 @@ +// +// WorkoutEndView.swift +// FeatureWorkoutInterface +// +// Created by 송영모 on 2023/06/21. +// + +import SwiftUI +import ComposableArchitecture + +import FeatureWorkoutInterface +import SharedDesignSystem +import SharedUtil + +extension WorkoutEndView { + public init(store: StoreOf) { + self.init(store: store) { + self.makeView(store: store) as! Content + } + } + + func makeView(store: StoreOf) -> some View { + WithViewStore(store, observe: { $0 }) { viewStore in + VStack { + self.titleView() + + self.resultView(viewStore: viewStore) + .offset(.init(width: 0, height: -40)) + .padding(.horizontal) + + self.workoutToolListView(store: store, viewStore: viewStore) + + Spacer() + + PumpingSubmitButton(title: "완료", completion: { + viewStore.send(.completeButtonTapped) + }) + .padding() + } + .navigationBarBackButtonHidden(true) + } + } + + @ViewBuilder + private func titleView() -> some View { + VStack(alignment: .leading, spacing: 12) { + Text("운동을 모두 끝냈어요!") + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(PumpingColors.colorGrey100.swiftUIColor) + + Text("오늘 한 운동 세트를 기록할 수 있어요") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(PumpingColors.colorGrey000.swiftUIColor) + + SharedDesignSystemAsset.Images.boy.swiftUIImage + + HStack { + Spacer() + } + } + .padding(.horizontal) + .background(Color.colorCyan300) + } + + @ViewBuilder + private func resultView(viewStore: ViewStoreOf) -> some View { + HStack { + Spacer() + + VStack(spacing: 4) { + Text("오늘 운동 시간") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(.colorCyan300) + + Text(DateManager.toClockString(from: viewStore.state.workoutTime)) + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(.colorGrey900) + } + + Spacer() + + Divider() + .frame(height: 54) + + Spacer() + + VStack(spacing: 4) { + Text("소모 칼로리") + .font(.pretendard(size: 15, type: .medium)) + .foregroundColor(.colorCyan300) + + Text("\(viewStore.state.workoutCalorie)kcal") + .font(.pretendard(size: 24, type: .bold)) + .foregroundColor(.colorGrey900) + } + + Spacer() + } + .frame(maxWidth: .infinity) + .padding() + .background(Color.colorGrey100) + .cornerRadius(12) + } + + @ViewBuilder + private func workoutToolListView(store: StoreOf, viewStore: ViewStoreOf) -> some View { + VStack { + HStack { + Text("오늘 한 운동 기구") + .font(.pretendard(size: 18, type: .bold)) + .foregroundColor(Color.colorGrey900) + + Spacer() + + Text("세트 기록") + .font(.pretendard(size: 16, type: .bold)) + .foregroundColor(Color.colorGrey600) + + Button(action: { + viewStore.send(.editButtonTapped) + }, label: { + Image(systemName: "highlighter") + .imageScale(.medium) + .foregroundColor(.colorCyan300) + }) + } + + ForEachStore(store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { + PumpingTextCellView(store: $0) + } + } + .padding(.horizontal) + } +} diff --git a/Projects/Feature/Workout/Sources/Root/WorkoutRootCompositionDIContainer.swift b/Projects/Feature/Workout/Sources/Root/WorkoutRootCompositionDIContainer.swift new file mode 100644 index 0000000..0a4c8ff --- /dev/null +++ b/Projects/Feature/Workout/Sources/Root/WorkoutRootCompositionDIContainer.swift @@ -0,0 +1,8 @@ +// +// WorkoutCompositionDIContainer.swift +// FeatureWorkout +// +// Created by 송영모 on 2023/06/21. +// + +import Foundation diff --git a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift b/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift similarity index 79% rename from Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift rename to Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift index 67f02c8..dd5b9a4 100644 --- a/Projects/Feature/Workout/Interface/Sources/Root/WorkoutRootView.swift +++ b/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift @@ -10,6 +10,7 @@ import SwiftUI import ComposableArchitecture import SharedDesignSystem +import FeatureWorkoutInterface public struct WorkoutRootView: View { public let store: StoreOf @@ -57,28 +58,33 @@ public struct WorkoutRootView: View { .navigationDestination(for: WorkoutScene.self) { scene in switch scene { case .home: - IfLetStore(self.store.scope(state: \.workoutHome, action: { .workoutHome($0) })) { - WorkoutHomeView(store: $0) + IfLetStore(self.store.scope(state: \.workoutHome, action: { .workoutHome($0) })) {_ in + EmptyView() +// WorkoutHomeView(store: $0) } case .start: - IfLetStore(self.store.scope(state: \.workoutStart, action: { .workoutStart($0) })) { - WorkoutStartView(store: $0) + IfLetStore(self.store.scope(state: \.workoutStart, action: { .workoutStart($0) })) {_ in + EmptyView() +// WorkoutStartView(store: $0) } case .timer: - IfLetStore(self.store.scope(state: \.workoutTimer, action: { .workoutTimer($0) })) { - WorkoutTimerView(store: $0) + IfLetStore(self.store.scope(state: \.workoutTimer, action: { .workoutTimer($0) })) {_ in + EmptyView() +// WorkoutTimerView(store: $0) } case .end: IfLetStore(self.store.scope(state: \.workoutEnd, action: { .workoutEnd($0) })) { - WorkoutEndView(store: $0) + EmptyView() + WorkoutEndDIContainer.shared.resolve(store: $0) } case .record: - IfLetStore(self.store.scope(state: \.workoutRecord, action: { .workoutRecord($0) })) { - WorkoutRecordView(store: $0) + IfLetStore(self.store.scope(state: \.workoutRecord, action: { .workoutRecord($0) })) {_ in + EmptyView() +// WorkoutRecordView(store: $0) } default: From f42a7d1dfd7c4abe51690ca4f0a3f7f68c88d40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=89=E1=85=A9=E1=86=BC=E1=84=8B=E1=85=A7=E1=86=BC?= =?UTF-8?q?=E1=84=86=E1=85=A9?= Date: Fri, 23 Jun 2023 14:22:31 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20view=EC=9D=98=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=B6=84=EB=A6=AC=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/End/WorkoutEndView.swift | 137 ------------------ .../Sources/End/WorkoutEndDIContainer.swift | 24 --- .../Workout/Sources/End/WorkoutEndView.swift | 20 ++- .../Sources/Root/WorkoutRootView.swift | 3 +- 4 files changed, 15 insertions(+), 169 deletions(-) delete mode 100644 Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift delete mode 100644 Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift diff --git a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift deleted file mode 100644 index de91ef5..0000000 --- a/Projects/Feature/Workout/Interface/Sources/End/WorkoutEndView.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// WorkoutEndView.swift -// FeatureWorkoutInterface -// -// Created by 송영모 on 2023/05/23. -// - -import SwiftUI - -import ComposableArchitecture - -import SharedDesignSystem -import SharedUtil - -//public struct WorkoutEndView: View { -// private let store: StoreOf -// private let content: () -> Content -// -// public init(store: StoreOf, content: @escaping () -> Content) { -// self.store = store -// self.content = content -// } -// -// public var body: some View { -// content() -// WithViewStore(self.store, observe: { $0 }) { viewStore in -// VStack { -// titleView() -// -// resultView(viewStore: viewStore) -// .offset(.init(width: 0, height: -40)) -// .padding(.horizontal) -// -// workoutToolListView(viewStore: viewStore) -// -// Spacer() -// -// PumpingSubmitButton(title: "완료", completion: { -// viewStore.send(.completeButtonTapped) -// }) -// .padding() -// } -// .navigationBarBackButtonHidden(true) -// } -// } -// -// @ViewBuilder -// private func titleView() -> some View { -// VStack(alignment: .leading, spacing: 12) { -// Text("운동을 모두 끝냈어요!") -// .font(.pretendard(size: 24, type: .bold)) -// .foregroundColor(PumpingColors.colorGrey100.swiftUIColor) -// -// Text("오늘 한 운동 세트를 기록할 수 있어요") -// .font(.pretendard(size: 15, type: .medium)) -// .foregroundColor(PumpingColors.colorGrey000.swiftUIColor) -// -// SharedDesignSystemAsset.Images.boy.swiftUIImage -// -// HStack { -// Spacer() -// } -// } -// .padding(.horizontal) -// .background(Color.colorCyan300) -// } -// -// @ViewBuilder -// private func resultView(viewStore: ViewStoreOf) -> some View { -// HStack { -// Spacer() -// -// VStack(spacing: 4) { -// Text("오늘 운동 시간") -// .font(.pretendard(size: 15, type: .medium)) -// .foregroundColor(.colorCyan300) -// -// Text(DateManager.toClockString(from: viewStore.state.workoutTime)) -// .font(.pretendard(size: 24, type: .bold)) -// .foregroundColor(.colorGrey900) -// } -// -// Spacer() -// -// Divider() -// .frame(height: 54) -// -// Spacer() -// -// VStack(spacing: 4) { -// Text("소모 칼로리") -// .font(.pretendard(size: 15, type: .medium)) -// .foregroundColor(.colorCyan300) -// -// Text("\(viewStore.state.workoutCalorie)kcal") -// .font(.pretendard(size: 24, type: .bold)) -// .foregroundColor(.colorGrey900) -// } -// -// Spacer() -// } -// .frame(maxWidth: .infinity) -// .padding() -// .background(Color.colorGrey100) -// .cornerRadius(12) -// } -// -// @ViewBuilder -// private func workoutToolListView(viewStore: ViewStoreOf) -> some View { -// VStack { -// HStack { -// Text("오늘 한 운동 기구") -// .font(.pretendard(size: 18, type: .bold)) -// .foregroundColor(Color.colorGrey900) -// -// Spacer() -// -// Text("세트 기록") -// .font(.pretendard(size: 16, type: .bold)) -// .foregroundColor(Color.colorGrey600) -// -// Button(action: { -// viewStore.send(.editButtonTapped) -// }, label: { -// Image(systemName: "highlighter") -// .imageScale(.medium) -// .foregroundColor(.colorCyan300) -// }) -// } -// -// ForEachStore(self.store.scope(state: \.workoutToolCells, action: WorkoutEndStore.Action.pumpingTextCell(id:action:))) { -// PumpingTextCellView(store: $0) -// } -// } -// .padding(.horizontal) -// } -//} diff --git a/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift b/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift deleted file mode 100644 index b77b0ef..0000000 --- a/Projects/Feature/Workout/Sources/End/WorkoutEndDIContainer.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// WorkoutEndDIContainer.swift -// FeatureWorkout -// -// Created by 송영모 on 2023/06/21. -// - -import SwiftUI - -import ComposableArchitecture - -import FeatureWorkoutInterface - -class WorkoutEndDIContainer { - static let shared = WorkoutEndDIContainer() - - private init() {} - - func resolve(store: StoreOf) -> WorkoutEndView { - return .init() { - self.makeView(store: store) - } - } -} diff --git a/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift b/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift index cacdfd4..fec3d98 100644 --- a/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift +++ b/Projects/Feature/Workout/Sources/End/WorkoutEndView.swift @@ -12,14 +12,14 @@ import FeatureWorkoutInterface import SharedDesignSystem import SharedUtil -extension WorkoutEndView { - public init(store: StoreOf) { - self.init(store: store) { - self.makeView(store: store) as! Content - } +public struct WorkoutEndViewImpl: View { + private let store: StoreOf + + init(store: StoreOf) { + self.store = store } - func makeView(store: StoreOf) -> some View { + public var body: some View { WithViewStore(store, observe: { $0 }) { viewStore in VStack { self.titleView() @@ -132,3 +132,11 @@ extension WorkoutEndView { .padding(.horizontal) } } + +extension WorkoutEndView { + public init(store: StoreOf) { + self.init(store: store) { + WorkoutEndViewImpl(store: store) + } + } +} diff --git a/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift b/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift index dd5b9a4..d0fbb0f 100644 --- a/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift +++ b/Projects/Feature/Workout/Sources/Root/WorkoutRootView.swift @@ -77,8 +77,7 @@ public struct WorkoutRootView: View { case .end: IfLetStore(self.store.scope(state: \.workoutEnd, action: { .workoutEnd($0) })) { - EmptyView() - WorkoutEndDIContainer.shared.resolve(store: $0) + WorkoutEndView(store: $0) } case .record: