feat(gift): 수령지 입력을 추가한다
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
final class GiftRecipientAddressViewModel: ObservableObject {
|
||||
@Published var recipientName: String = ""
|
||||
@Published var recipientPhoneNumber: String = ""
|
||||
@Published var recipientZipCode: String = ""
|
||||
@Published var recipientAddress: String = ""
|
||||
@Published var recipientAddressDetail: String = ""
|
||||
@Published var recipientTermsAgreed: Bool = false
|
||||
@Published var recipientPrivacyAgreed: Bool = false
|
||||
|
||||
@Published private(set) var isSubmitting = false
|
||||
@Published var errorMessage = ""
|
||||
@Published var isShowPopup = false
|
||||
@Published var isShowSuccessToast = false
|
||||
let successMessage = "배송지 입력 완료"
|
||||
|
||||
private let applicationNo: String
|
||||
private let onSubmitted: () -> Void
|
||||
private let repository = GiftRepository()
|
||||
private var mutationSubscription: AnyCancellable?
|
||||
@Published private(set) var hasSubmitted = false
|
||||
private var hasNotifiedSubmission = false
|
||||
|
||||
init(applicationNo: String, onSubmitted: @escaping () -> Void) {
|
||||
self.applicationNo = applicationNo
|
||||
self.onSubmitted = onSubmitted
|
||||
}
|
||||
|
||||
var canSubmit: Bool {
|
||||
!isSubmitting && !hasSubmitted && recipientTermsAgreed && recipientPrivacyAgreed
|
||||
&& GiftContactInputRule.name.acceptsSubmission(recipientName)
|
||||
&& GiftContactInputRule.phoneNumber.acceptsSubmission(recipientPhoneNumber)
|
||||
&& [recipientZipCode, recipientAddress].allSatisfy {
|
||||
!$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
func submit() {
|
||||
guard canSubmit else { return }
|
||||
|
||||
isSubmitting = true
|
||||
errorMessage = ""
|
||||
isShowPopup = false
|
||||
|
||||
let request = SubmitGiftRecipientAddressRequest(
|
||||
recipientName: recipientName.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
recipientPhoneNumber: recipientPhoneNumber.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
recipientZipCode: recipientZipCode.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
recipientAddress: recipientAddress.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
recipientAddressDetail: recipientAddressDetail.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
recipientTermsAgreed: recipientTermsAgreed,
|
||||
recipientPrivacyAgreed: recipientPrivacyAgreed
|
||||
)
|
||||
mutationSubscription = repository.submitRecipientAddress(applicationNo: applicationNo, request: request)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] result in
|
||||
guard let self, !self.hasSubmitted else { return }
|
||||
if case .failure(let error) = result {
|
||||
self.finishFailure(data: error.response?.data)
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let self, !self.hasSubmitted else { return }
|
||||
do {
|
||||
let decoded = try JSONDecoder().decode(ApiResponseWithoutData.self, from: response.data)
|
||||
guard decoded.success else {
|
||||
self.finishFailure(data: response.data)
|
||||
return
|
||||
}
|
||||
self.hasSubmitted = true
|
||||
self.isSubmitting = false
|
||||
self.isShowSuccessToast = true
|
||||
} catch {
|
||||
self.finishFailure(data: response.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func successToastDidDismiss() {
|
||||
guard hasSubmitted, !isShowSuccessToast, !hasNotifiedSubmission else { return }
|
||||
|
||||
hasNotifiedSubmission = true
|
||||
onSubmitted()
|
||||
}
|
||||
|
||||
private func finishFailure(data: Data?) {
|
||||
struct ErrorResponse: Decodable {
|
||||
let message: String?
|
||||
}
|
||||
|
||||
let decoded = data.flatMap { try? JSONDecoder().decode(ErrorResponse.self, from: $0) }
|
||||
let message = decoded?.message?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
isSubmitting = false
|
||||
errorMessage = message.isEmpty ? I18n.Common.commonError : message
|
||||
isShowPopup = true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user