This repository has been archived by the owner on Aug 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [Add] 개선제안 뷰 틀 구현 * [Design] WeaveTextView 구현 * [Add] Suggestion Feature 액션 구조 생성 * [Add] 개선사항 제안 기능 구현 * [Design] Empty View multiline setting * [Add] 뒤로가기 액션 추가
- Loading branch information
1 parent
6e06c79
commit 950a38e
Showing
8 changed files
with
302 additions
and
2 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
weave-iOS/Projects/App/Sources/MyPage/Setting/Feature/AppSuggestionFeature.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// AppSuggestionFeature.swift | ||
// Weave-ios | ||
// | ||
// Created by 김지수 on 4/22/24. | ||
// | ||
|
||
import Foundation | ||
import ComposableArchitecture | ||
import Services | ||
import CoreKit | ||
|
||
struct AppSuggestionFeature: Reducer { | ||
@Dependency(\.coordinator) var appCoordinator | ||
@Dependency(\.dismiss) var dismiss | ||
|
||
struct State: Equatable { | ||
@BindingState var inputText: String = "" | ||
@BindingState var isShowCompleteAlert: Bool = false | ||
} | ||
|
||
enum Action: BindableAction { | ||
case didTappedDismiss | ||
case didTappedSummitButton | ||
case requestSuggestionText | ||
case replaceInputText(text: String) | ||
case didSuccessedSummit | ||
case didTappedUserCompleteButton | ||
case binding(BindingAction<State>) | ||
} | ||
|
||
var body: some ReducerOf<Self> { | ||
BindingReducer() | ||
Reduce { state, action in | ||
switch action { | ||
case .didTappedDismiss: | ||
return .run { send in | ||
await dismiss() | ||
} | ||
case .replaceInputText(let text): | ||
state.inputText = text | ||
return .none | ||
case .didTappedSummitButton: | ||
return .send(.requestSuggestionText) | ||
case .requestSuggestionText: | ||
return .run { [text = state.inputText] send in | ||
try await requestSuggestionText(text: text) | ||
await send.callAsFunction(.didSuccessedSummit) | ||
} catch: { error, send in | ||
print(error) | ||
} | ||
case .didSuccessedSummit: | ||
state.isShowCompleteAlert = true | ||
return .none | ||
case .didTappedUserCompleteButton: | ||
return .run { send in | ||
await dismiss() | ||
} | ||
case .binding(_): | ||
return .none | ||
} | ||
} | ||
} | ||
|
||
func requestSuggestionText(text: String) async throws { | ||
let endPoint = APIEndpoints.appSuggestionRequest(text: text) | ||
let provider = APIProvider() | ||
try await provider.requestWithNoResponse(with: endPoint, successCode: 201) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
...rojects/App/Sources/MyPage/Setting/Model/Network/RequestDTO/AppSuggestionRequestDTO.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// AppSuggestionRequestDTO.swift | ||
// Weave-ios | ||
// | ||
// Created by 김지수 on 4/23/24. | ||
// | ||
|
||
import Foundation | ||
import Services | ||
import CoreKit | ||
|
||
struct AppSuggestionRequestDTO: Codable { | ||
let contents: String | ||
} | ||
|
||
extension APIEndpoints { | ||
static func appSuggestionRequest(text: String) -> EndPoint<EmptyResponse> { | ||
let requestDTO = AppSuggestionRequestDTO(contents: text) | ||
return EndPoint( | ||
path: "api/suggestions", | ||
method: .post, | ||
bodyParameters: requestDTO, | ||
headers: [ | ||
"Authorization": "Bearer \(UDManager.accessToken)" | ||
] | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
weave-iOS/Projects/App/Sources/MyPage/Setting/View/AppSuggestionView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// | ||
// AppSuggestionView.swift | ||
// Weave-ios | ||
// | ||
// Created by 김지수 on 4/22/24. | ||
// | ||
|
||
import SwiftUI | ||
import DesignSystem | ||
import ComposableArchitecture | ||
|
||
struct AppSuggestionView: View { | ||
let store: StoreOf<AppSuggestionFeature> | ||
let textLimit = 2000 | ||
@State var isShowTextLimitAlert: Bool = false | ||
|
||
var body: some View { | ||
WithViewStore(store, observe: { $0 }) { viewStore in | ||
VStack { | ||
ScrollView { | ||
VStack { | ||
VStack(spacing: 12) { | ||
Text("개선할 점을 알려주세요") | ||
.font(.pretendard(._600, size: 24)) | ||
Text("여러분의 의견은 위브에 아주 큰 도움이 돼요!") | ||
.font(.pretendard(._500, size: 16)) | ||
} | ||
.multilineTextAlignment(.center) | ||
.padding(.top, 38) | ||
.padding(.bottom, 58) | ||
|
||
WeaveTextView( | ||
text: viewStore.$inputText, | ||
placeholder: "의견을 작성해 주세요.", | ||
height: 188 | ||
) | ||
.onChange(of: viewStore.inputText) { oldValue, newValue in | ||
if newValue.count > textLimit { | ||
isShowTextLimitAlert = true | ||
let newText = viewStore.inputText.prefix(textLimit) | ||
viewStore.send(.replaceInputText(text: String(newText))) | ||
} | ||
} | ||
} | ||
.padding(.horizontal, 16) | ||
} | ||
WeaveButton( | ||
title: "제출하기", | ||
size: .large, | ||
isEnabled: !viewStore.inputText.isEmpty | ||
) { | ||
viewStore.send(.didTappedSummitButton) | ||
} | ||
.padding(.horizontal, 16) | ||
} | ||
.weaveAlert( | ||
isPresented: $isShowTextLimitAlert, | ||
title: "🙇♂️\n최대 2000자까지 작성 가능해요.", | ||
primaryButtonTitle: "확인했어요", | ||
primaryAction: { | ||
viewStore.send(.didTappedUserCompleteButton) | ||
} | ||
) | ||
.weaveAlert( | ||
isPresented: viewStore.$isShowCompleteAlert, | ||
title: "🙇♂️\n의견이 정상적으로 제출됐어요.", | ||
message: "소중한 의견 감사합니다!", | ||
primaryButtonTitle: "확인했어요", | ||
primaryAction: { | ||
viewStore.send(.didTappedUserCompleteButton) | ||
} | ||
) | ||
.navigationTitle("위브 개선 제안") | ||
.navigationBarTitleDisplayMode(.inline) | ||
.navigationBarBackButtonHidden() | ||
.toolbar { | ||
ToolbarItem(placement: .topBarLeading) { | ||
Button { | ||
viewStore.send(.didTappedDismiss) | ||
} label: { | ||
Image(systemName: "chevron.left") | ||
} | ||
.foregroundStyle(.white) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
AppSuggestionView(store: .init(initialState: AppSuggestionFeature.State(), reducer: { | ||
AppSuggestionFeature() | ||
})) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.