diff --git a/project/Projects/Data/ConcreteRepository/Auth/DefaultAuthRepository.swift b/project/Projects/Data/ConcreteRepository/Auth/DefaultAuthRepository.swift index 1ffb6834..e0440f27 100644 --- a/project/Projects/Data/ConcreteRepository/Auth/DefaultAuthRepository.swift +++ b/project/Projects/Data/ConcreteRepository/Auth/DefaultAuthRepository.swift @@ -80,6 +80,12 @@ public extension DefaultAuthRepository { .request(api: .requestCenterJoin, with: .withToken) .mapToVoid() } + + func setNewPassword(phoneNumber: String, password: String) -> Single { + networkService + .request(api: .makeNewPassword(phoneNumber: phoneNumber, newPassword: password), with: .plain) + .mapToVoid() + } } // MARK: Worker auth diff --git a/project/Projects/Data/DataSource/API/AuthAPI.swift b/project/Projects/Data/DataSource/API/AuthAPI.swift index 1ada1c42..c7b16bc7 100644 --- a/project/Projects/Data/DataSource/API/AuthAPI.swift +++ b/project/Projects/Data/DataSource/API/AuthAPI.swift @@ -27,6 +27,8 @@ public enum AuthAPI { case deregisterCenterAccount(reason: String, password: String) case signoutCenterAccount + case makeNewPassword(phoneNumber: String, newPassword: String) + // Worker case registerWorkerAccount(data: Data) case workerLogin(phoneNumber: String, verificationNumber: String) @@ -69,6 +71,10 @@ extension AuthAPI: BaseAPI { return .post + case .makeNewPassword: + return .patch + + case .registerWorkerAccount: return .post case .workerLogin: @@ -83,17 +89,17 @@ extension AuthAPI: BaseAPI { public var path: String { switch self { case .startPhoneNumberAuth: - "common/send" + "/common/send" case .checkAuthNumber: - "common/confirm" + "/common/confirm" case .reissueToken: - "common/refresh" + "/common/refresh" case .authenticateBusinessNumber(let businessNumber): - "center/authentication/\(businessNumber)" + "/center/authentication/\(businessNumber)" case .checkIdDuplication(id: let id): - "center/validation/\(id)" + "/center/validation/\(id)" case .centerJoinStatus: "/center/join/status" @@ -102,23 +108,26 @@ extension AuthAPI: BaseAPI { case .registerCenterAccount: - "center/join" + "/center/join" case .centerLogin: - "center/login" + "/center/login" case .signoutCenterAccount: - "center/logout" + "/center/logout" case .deregisterCenterAccount: - "center/withdraw" + "/center/withdraw" + + case .makeNewPassword: + "/center/password/new" case .registerWorkerAccount: - "carer/join" + "/carer/join" case .workerLogin: - "carer/login" + "/carer/login" case .signoutWorkerAccount: - "carer/logout" + "/carer/logout" case .deregisterWorkerAccount: - "carer/withdraw" + "/carer/withdraw" } } @@ -136,6 +145,9 @@ extension AuthAPI: BaseAPI { case .deregisterCenterAccount(let reason, let password): params["reason"] = reason params["password"] = password + case .makeNewPassword(let phoneNumber, let newPassword): + params["phoneNumber"] = phoneNumber + params["newPassword"] = newPassword case .reissueToken(let refreshToken): params["refreshToken"] = refreshToken case .workerLogin(let phoneNumber, let verificationNumber): @@ -172,6 +184,8 @@ extension AuthAPI: BaseAPI { return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding) case .deregisterCenterAccount: return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding) + case .makeNewPassword: + return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding) case .reissueToken: return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding) case .registerWorkerAccount(let data): diff --git a/project/Projects/Domain/ConcreteUseCase/Auth/DefaultAuthUseCase.swift b/project/Projects/Domain/ConcreteUseCase/Auth/DefaultAuthUseCase.swift index c09d1710..d3a8f94f 100644 --- a/project/Projects/Domain/ConcreteUseCase/Auth/DefaultAuthUseCase.swift +++ b/project/Projects/Domain/ConcreteUseCase/Auth/DefaultAuthUseCase.swift @@ -82,4 +82,8 @@ public class DefaultAuthUseCase: AuthUseCase { public func checkCenterJoinStatus() -> Single> { convert(task: authRepository.getCenterJoinStatus()) } + + public func setNewPassword(phoneNumber: String, password: String) -> Single> { + convert(task: authRepository.setNewPassword(phoneNumber: phoneNumber, password: password)) + } } diff --git a/project/Projects/Domain/RepositoryInterface/Auth/AuthRepository.swift b/project/Projects/Domain/RepositoryInterface/Auth/AuthRepository.swift index f3297653..cf433a21 100644 --- a/project/Projects/Domain/RepositoryInterface/Auth/AuthRepository.swift +++ b/project/Projects/Domain/RepositoryInterface/Auth/AuthRepository.swift @@ -15,8 +15,9 @@ public protocol AuthRepository: RepositoryBase { func requestCenterLogin(id: String, password: String) -> Single func signoutCenterAccount() -> Single func deregisterCenterAccount(reasons: [DeregisterReasonVO], password: String) -> Single - func getCenterJoinStatus() -> RxSwift.Single - func requestCenterJoin() -> RxSwift.Single + func getCenterJoinStatus() -> Single + func requestCenterJoin() -> Single + func setNewPassword(phoneNumber: String, password: String) -> Single // MARK: Worker diff --git a/project/Projects/Domain/UseCaseInterface/Auth/AuthUseCase.swift b/project/Projects/Domain/UseCaseInterface/Auth/AuthUseCase.swift index e9bb6ecb..78e31333 100644 --- a/project/Projects/Domain/UseCaseInterface/Auth/AuthUseCase.swift +++ b/project/Projects/Domain/UseCaseInterface/Auth/AuthUseCase.swift @@ -9,20 +9,9 @@ import Foundation import RxSwift import Entity -/// 요구사항 -/// - #1. 센터 회원가입 실행 -/// - #2. 센터 로그인 실행 -/// - #3. 샌터 회원 탈퇴 -/// - #4. 샌터 회원 로그아웃 -/// -/// - #5. 요양보호사 회원가입 실행 -/// - #6. 요양보호사 로그인 실행 -/// - #7. 요양보호사 회원탈퇴 실행 -/// - #8. 요양보호사 로그아웃 - public protocol AuthUseCase: UseCaseBase { - // #1. + /// 센터 회원가입 실행 /// - parameters: /// - registerState: CenterRegisterState @@ -30,7 +19,7 @@ public protocol AuthUseCase: UseCaseBase { registerState: CenterRegisterState ) -> Single> - // #2. + /// 센터 로그인 실행 /// - parameters: /// - id: String @@ -40,18 +29,23 @@ public protocol AuthUseCase: UseCaseBase { password: String ) -> Single> - // #5 + /// 센터 인증여부 확인 + func checkCenterJoinStatus() -> Single> + + + /// 센터 비밀번호 재설정 + func setNewPassword(phoneNumber: String, password: String) -> Single> + + /// 요양 보호사 회원가입 실행 func registerWorkerAccount( registerState: WorkerRegisterState ) -> Single> - // #6 + + /// 요양 보호사 로그인 실행 func loginWorkerAccount( phoneNumber: String, authNumber: String ) -> Single> - - /// 센터 인증여부 확인 - func checkCenterJoinStatus() -> Single> } diff --git a/project/Projects/Presentation/DSKit/Sources/CommonUI/SnackBar/IdleSnackBar.swift b/project/Projects/Presentation/DSKit/Sources/CommonUI/SnackBar/IdleSnackBar.swift index 169dc732..e56e81c3 100644 --- a/project/Projects/Presentation/DSKit/Sources/CommonUI/SnackBar/IdleSnackBar.swift +++ b/project/Projects/Presentation/DSKit/Sources/CommonUI/SnackBar/IdleSnackBar.swift @@ -70,6 +70,10 @@ public class IdleSnackBar: UIView { } NSLayoutConstraint.activate([ + + titleIcon.widthAnchor.constraint(equalToConstant: 24), + titleIcon.heightAnchor.constraint(equalToConstant: 24), + mainStack.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor), mainStack.leftAnchor.constraint(equalTo: self.layoutMarginsGuide.leftAnchor), mainStack.rightAnchor.constraint(equalTo: self.layoutMarginsGuide.rightAnchor), diff --git a/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Center/CenterSetNewPasswordCoordinator.swift b/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Center/CenterSetNewPasswordCoordinator.swift index 4eafa6b2..42385c06 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Center/CenterSetNewPasswordCoordinator.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Center/CenterSetNewPasswordCoordinator.swift @@ -8,6 +8,8 @@ import UIKit import PresentationCore import UseCaseInterface +import BaseFeature +import DSKit enum SetNewPasswordStage: Int { @@ -56,14 +58,16 @@ public class CenterSetNewPasswordCoordinator: ChildCoordinator { public func start() { let vm = CenterSetNewPasswordViewModel( + coordinator: self, authUseCase: authUseCase, inputValidationUseCase: inputValidationUseCase ) // stageViewControllerss에 자기자신과 ViewModel할당 + self.stageViewControllers = [ ValidatePhoneNumberViewController(coordinator: self, viewModel: vm), - ValidateNewPasswordViewController(coordinator: self, viewModel: vm) + ValidateNewPasswordViewController(viewModel: vm) ] let pageViewController = UIPageViewController( @@ -74,21 +78,38 @@ public class CenterSetNewPasswordCoordinator: ChildCoordinator { self.pageViewController = pageViewController - let viewController = CenterSetNewPasswordController( + let vc = CenterSetNewPasswordController( pageViewController: pageViewController, pageCount: stageViewControllers.count ) - viewController.coordinator = self + vc.bind(viewModel: vm) + vc.coordinator = self - navigationController.pushViewController(viewController, animated: true) + navigationController.pushViewController(vc, animated: true) excuteStage(.phoneNumber, moveTo: .next) } public func coordinatorDidFinish() { stageViewControllers = [] + popViewController() parent?.removeChildCoordinator(self) } + + public func coordinatorDidFinishWithSnackBar(ro: IdleSnackBarRO) { + let belowIndex = navigationController.children.count-2 + + if belowIndex >= 0 { + let belowVC = navigationController.children[belowIndex] + + if let baseVC = belowVC as? BaseViewController { + + baseVC.viewModel?.addSnackBar(ro: ro) + } + } + + coordinatorDidFinish() + } } extension CenterSetNewPasswordCoordinator { @@ -114,7 +135,6 @@ extension CenterSetNewPasswordCoordinator { currentStage = stage switch stage { case .findPasswordFinished, .finish: - popViewController() coordinatorDidFinish() default: let vc = stageViewControllers[stage.rawValue-1] diff --git a/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Worker/WorkerRegisterCoordinator.swift b/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Worker/WorkerRegisterCoordinator.swift index eacd0eeb..3ec1061d 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Worker/WorkerRegisterCoordinator.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/Coordinator/Worker/WorkerRegisterCoordinator.swift @@ -38,24 +38,19 @@ public class WorkerRegisterCoordinator: ChildCoordinator { public weak var viewControllerRef: UIViewController? weak var pageViewController: UIPageViewController? + + let inputValidationUseCase: AuthInputValidationUseCase + let authUseCase: AuthUseCase + // MARK: Stage var stageViewControllers: [UIViewController] = [] private var currentStage: WorkerRegisterStage! public init(dependency: Dependency) { + self.inputValidationUseCase = dependency.inputValidationUseCase + self.authUseCase = dependency.authUseCase self.navigationController = dependency.navigationController - - let vm = WorkerRegisterViewModel( - inputValidationUseCase: dependency.inputValidationUseCase, - authUseCase: dependency.authUseCase - ) - - self.stageViewControllers = [ - ValidatePhoneNumberViewController(coordinator: self, viewModel: vm), - EntetPersonalInfoViewController(coordinator: self, viewModel: vm), - EnterAddressViewController(coordinator: self, viewModel: vm), - ] } deinit { @@ -70,18 +65,30 @@ public class WorkerRegisterCoordinator: ChildCoordinator { options: nil ) + let vm = WorkerRegisterViewModel( + inputValidationUseCase: inputValidationUseCase, + authUseCase: authUseCase + ) + + self.stageViewControllers = [ + ValidatePhoneNumberViewController(coordinator: self, viewModel: vm), + EntetPersonalInfoViewController(coordinator: self, viewModel: vm), + EnterAddressViewController(coordinator: self, viewModel: vm), + ] + self.pageViewController = pageViewController - let viewController = WorkerRegisterViewController( + let vc = WorkerRegisterViewController( pageCount: stageViewControllers.count, pageViewController: pageViewController ) + vc.bind(viewModel: vm) - viewController.coordinator = self + vc.coordinator = self - viewControllerRef = viewController + viewControllerRef = vc - navigationController.pushViewController(viewController, animated: true) + navigationController.pushViewController(vc, animated: true) excuteStage(.info, moveTo: .next) } diff --git a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/CenterSetNewPasswordController.swift b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/CenterSetNewPasswordController.swift index c9451cf7..c4e768fd 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/CenterSetNewPasswordController.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/CenterSetNewPasswordController.swift @@ -12,7 +12,7 @@ import RxCocoa import PresentationCore import BaseFeature -class CenterSetNewPasswordController: DisposableViewController { +class CenterSetNewPasswordController: BaseViewController { // Init var pageViewController: UIPageViewController @@ -21,8 +21,6 @@ class CenterSetNewPasswordController: DisposableViewController { var coordinator: CenterSetNewPasswordCoordinator? - let disposeBag = DisposeBag() - public init(pageViewController: UIPageViewController, pageCount: Int) { self.pageViewController = pageViewController self.pageCount = pageCount diff --git a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/ValidateNewPasswordViewController.swift b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/ValidateNewPasswordViewController.swift index 723acd36..31b2957c 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/ValidateNewPasswordViewController.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Login/ValidateNewPasswordViewController.swift @@ -16,15 +16,12 @@ public protocol ChangePasswordSuccessInputable { var changePasswordButtonClicked: PublishRelay { get } } -public protocol ChangePasswordSuccessOutputable { - var changePasswordValidation: Driver? { get set } -} -class ValidateNewPasswordViewController: BaseViewController +class ValidateNewPasswordViewController: UIViewController where T.Input: SetPasswordInputable & ChangePasswordSuccessInputable, - T.Output: SetPasswordOutputable & ChangePasswordSuccessOutputable, T: BaseViewModel { + T.Output: SetPasswordOutputable { - var coordinator: Coordinator? + let viewModel: T // View private let processTitle: IdleLabel = { @@ -89,14 +86,12 @@ where T.Input: SetPasswordInputable & ChangePasswordSuccessInputable, return button }() - public init(coordinator: Coordinator, viewModel: T) { - - self.coordinator = coordinator - + let disposeBag = DisposeBag() + + public init(viewModel: T) { + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) - super.bind(viewModel: viewModel) - setAppearance() setAutoLayout() initialUISettuing() @@ -174,8 +169,6 @@ where T.Input: SetPasswordInputable & ChangePasswordSuccessInputable, func setObservable() { - guard let viewModel = self.viewModel as? T else { return } - // MARK: Input let input = viewModel.input @@ -223,22 +216,6 @@ where T.Input: SetPasswordInputable & ChangePasswordSuccessInputable, } }) .disposed(by: disposeBag) - - output - .changePasswordValidation? - .drive (onNext: { [weak self] isSuccess in - - if isSuccess { - // 비밀번호 변경 성공 - self?.coordinator?.next() - - } else { - // 비밀번호 변경 실패 - self?.ctaButton.setEnabled(true) - } - }) - .disposed(by: disposeBag) - } private func onPasswordMatched() { diff --git a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Register/SetIdPasswordViewController.swift b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Register/SetIdPasswordViewController.swift index 418dcaab..9db1317e 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Register/SetIdPasswordViewController.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/View/Center/Register/SetIdPasswordViewController.swift @@ -288,7 +288,17 @@ where T.Input: SetIdInputable & SetPasswordInputable & CTAButtonEnableInputable, let idDuplicationValidation = output .idDuplicationValidation? .map { [weak self] isSuccess in - self?.idField.idleTextField.setEnabled(isSuccess) + + self?.idField.idleTextField.setEnabled(true) + + if !isSuccess { + self?.idField.idleTextField.textField.textString = "" + self?.showAlert(vo: .init( + title: "사용불가한 아이디", + message: "다른 아이디를 사용해주세요.") + ) + } + return isSuccess } .asObservable() ?? .empty() diff --git a/project/Projects/Presentation/Feature/Auth/Sources/View/Common/Register/ValidatePhoneNumberViewController.swift b/project/Projects/Presentation/Feature/Auth/Sources/View/Common/Register/ValidatePhoneNumberViewController.swift index f88f75ef..cb73b575 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/View/Common/Register/ValidatePhoneNumberViewController.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/View/Common/Register/ValidatePhoneNumberViewController.swift @@ -32,16 +32,14 @@ public protocol AuthPhoneNumberOutputable { // 요양보호사 로그인에 성공한 경우(요양보호사 한정 로직) var loginValidation: Driver? { get set } } -public extension AuthPhoneNumberOutputable { - var loginValidation: Driver? { get { nil } set { } } -} -class ValidatePhoneNumberViewController: BaseViewController +class ValidatePhoneNumberViewController: UIViewController where T.Input: AuthPhoneNumberInputable, - T.Output: AuthPhoneNumberOutputable, T: BaseViewModel { + T.Output: AuthPhoneNumberOutputable { var coordinator: Coordinator? + let viewModel: T // View private let processTitle: ResizableUILabel = { @@ -114,16 +112,17 @@ where return button }() + let disposeBag = DisposeBag() + public init( coordinator: Coordinator? = nil, viewModel: T ) { self.coordinator = coordinator + self.viewModel = viewModel super.init(nibName: nil, bundle: nil) - super.bind(viewModel: viewModel) - setAppearance() setAutoLayout() initialUISettuing() @@ -203,10 +202,7 @@ where ctaButton.setEnabled(false) } - private func setObservable() { - - guard let viewModel = self.viewModel as? T else { return } - + public func setObservable() { // MARK: Input let input = viewModel.input diff --git a/project/Projects/Presentation/Feature/Auth/Sources/View/Worker/WorkerRegisterViewController.swift b/project/Projects/Presentation/Feature/Auth/Sources/View/Worker/WorkerRegisterViewController.swift index 62ce45ff..745c67c6 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/View/Worker/WorkerRegisterViewController.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/View/Worker/WorkerRegisterViewController.swift @@ -12,7 +12,7 @@ import RxSwift import PresentationCore import BaseFeature -class WorkerRegisterViewController: DisposableViewController { +class WorkerRegisterViewController: BaseViewController { var coordinator: WorkerRegisterCoordinator? @@ -21,10 +21,8 @@ class WorkerRegisterViewController: DisposableViewController { let pageCount: Int // View - let navigationBar: NavigationBarType1 = { - let bar = NavigationBarType1( - navigationTitle: "요양보호사 회원가입" - ) + let navigationBar: IdleNavigationBar = { + let bar = IdleNavigationBar(titleText: "요양보호사 회원가입") return bar }() @@ -37,8 +35,6 @@ class WorkerRegisterViewController: DisposableViewController { return view }() - private let disposeBag = DisposeBag() - init( pageCount: Int, pageViewController: UIPageViewController @@ -76,9 +72,9 @@ class WorkerRegisterViewController: DisposableViewController { NSLayoutConstraint.activate([ - navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), - navigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 12), - navigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -12), + navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + navigationBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + navigationBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), statusBar.topAnchor.constraint(equalTo: navigationBar.bottomAnchor, constant: 7), statusBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), @@ -93,7 +89,7 @@ class WorkerRegisterViewController: DisposableViewController { func setObservable() { navigationBar - .eventPublisher + .backButton.rx.tap .subscribe { [weak self] _ in self?.coordinator?.prev() } @@ -109,7 +105,6 @@ class WorkerRegisterViewController: DisposableViewController { .disposed(by: disposeBag) } - func cleanUp() { coordinator?.stageViewControllers = [] diff --git a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/AuthInOutStreamManager/AuthInOutStreamManager+PhoneNumber.swift b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/AuthInOutStreamManager/AuthInOutStreamManager+PhoneNumber.swift index eb40ab57..666cc220 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/AuthInOutStreamManager/AuthInOutStreamManager+PhoneNumber.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/AuthInOutStreamManager/AuthInOutStreamManager+PhoneNumber.swift @@ -55,6 +55,7 @@ public extension AuthInOutStreamManager { #endif return useCase.requestPhoneNumberAuthentication(phoneNumber: formatted) } + .share() output .phoneNumberValidation = phoneNumberAuthRequestResult @@ -180,7 +181,9 @@ public extension AuthInOutStreamManager { } failureAlert - .subscribe(input.alert) + .subscribe(onNext: { [input] alertVO in + input.alert.onNext(alertVO) + }) .disposed(by: disposeBag) } } diff --git a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Login/CenterSetNewPasswordViewModel.swift b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Login/CenterSetNewPasswordViewModel.swift index 60213e6c..5209bbf1 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Login/CenterSetNewPasswordViewModel.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Login/CenterSetNewPasswordViewModel.swift @@ -17,75 +17,94 @@ public class CenterSetNewPasswordViewModel: BaseViewModel, ViewModelType { // Init let authUseCase: AuthUseCase let inputValidationUseCase: AuthInputValidationUseCase + weak var coordinator: CenterSetNewPasswordCoordinator? public var input: Input = .init() public var output: Output = .init() // State private var validPassword: String? + private var authenticatedPhoneNumebr: String? public init( + coordinator: CenterSetNewPasswordCoordinator, authUseCase: AuthUseCase, inputValidationUseCase: AuthInputValidationUseCase) { - self.authUseCase = authUseCase - self.inputValidationUseCase = inputValidationUseCase + self.coordinator = coordinator + self.authUseCase = authUseCase + self.inputValidationUseCase = inputValidationUseCase super.init() - setObservable() - } - - deinit { - printIfDebug("deinit \(Self.self)") - } - - func setObservable() { - - // 비밀번호 - AuthInOutStreamManager.passwordInOut( - input: input, - output: output, - useCase: inputValidationUseCase) { [weak self] validPassword in - // 🚀 상태추적 🚀 - self?.validPassword = validPassword - } - - // 휴대전화 인증 - AuthInOutStreamManager.validatePhoneNumberInOut( + // 비밀번호 + AuthInOutStreamManager.passwordInOut( + input: input, + output: output, + useCase: inputValidationUseCase) { [weak self] validPassword in + // 🚀 상태추적 🚀 + self?.validPassword = validPassword + } + + // 휴대전화 인증 + AuthInOutStreamManager.validatePhoneNumberInOut( input: input, output: output, useCase: inputValidationUseCase, - disposeBag: disposeBag - ) { _ in } - - changePasswordInOut() - } - - private func changePasswordInOut() { - - let changePasswordResult = input.changePasswordButtonClicked - .flatMap { [weak self] _ in - - printIfDebug("변경 요청 비밀번호 \(self?.validPassword ?? "")") - - // TODO: 비밀번호 변경 API 연동 - // 이벤트 전송 - return Single.just(Result.success(())) - } - .share() - - output.changePasswordValidation = changePasswordResult - .map { result in - switch result { - case .success: - printIfDebug("비밀번호 변경 성공") - return true - case .failure(let error): - printIfDebug("비밀번호 변경 실패") - return false + disposeBag: disposeBag) { [weak self] phoneNumber in + // 🚀 상태추적 🚀 + self?.authenticatedPhoneNumebr = phoneNumber + } + + let changePasswordResult = input.changePasswordButtonClicked + .compactMap({ [weak self] _ -> (String, String)? in + + guard let phoneNumber = self?.authenticatedPhoneNumebr, let validPassword = self?.validPassword else { + return nil + } + + return (phoneNumber, validPassword) + }) + .flatMap { [authUseCase] (phoneNumber, validPassword) in + + authUseCase + .setNewPassword(phoneNumber: phoneNumber, password: validPassword) } - } - .asDriver(onErrorJustReturn: false) + .share() + + changePasswordResult + .subscribe(onNext: { + [weak self] result in + + guard let self else { return } + + switch result { + case .success: + self.coordinator? + .coordinatorDidFinishWithSnackBar( + ro: .init( + titleText: "비밀번호 변경 성공" + ) + ) + case .failure(let error): + self.alert.onNext( + .init( + title: "비밀번호 변경 실패", + message: error.message + ) + ) + } + }) + .disposed(by: disposeBag) + + input.alert + .subscribe(onNext: { [weak self] alertVO in + self?.alert.onNext(alertVO) + }) + .disposed(by: disposeBag) + } + + deinit { + printIfDebug("deinit \(Self.self)") } } @@ -120,8 +139,7 @@ public extension CenterSetNewPasswordViewModel { // Password public var passwordValidation: Driver? - // Change password - public var changePasswordValidation: Driver? + public var loginValidation: Driver? } } @@ -133,4 +151,3 @@ extension CenterSetNewPasswordViewModel.Input: SetPasswordInputable { } extension CenterSetNewPasswordViewModel.Output: SetPasswordOutputable { } extension CenterSetNewPasswordViewModel.Input: ChangePasswordSuccessInputable { } -extension CenterSetNewPasswordViewModel.Output: ChangePasswordSuccessOutputable { } diff --git a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Register/CenterRegisterViewModel.swift b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Register/CenterRegisterViewModel.swift index 2cd49294..1ec0e451 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Register/CenterRegisterViewModel.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Center/Register/CenterRegisterViewModel.swift @@ -70,6 +70,10 @@ public class CenterRegisterViewModel: BaseViewModel, ViewModelType { // 🚀 상태추적 🚀 self?.stateObject.password = validPassword } + + input.alert + .bind(to: self.alert) + .disposed(by: disposeBag) } deinit { @@ -134,6 +138,7 @@ extension CenterRegisterViewModel { // Register success public var registerValidation: Driver? + public var loginValidation: Driver? } } diff --git a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Worker/Register/WorkerRegisterViewModel.swift b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Worker/Register/WorkerRegisterViewModel.swift index a13f16f8..f2fcac44 100644 --- a/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Worker/Register/WorkerRegisterViewModel.swift +++ b/project/Projects/Presentation/Feature/Auth/Sources/ViewModel/Worker/Register/WorkerRegisterViewModel.swift @@ -92,34 +92,22 @@ public class WorkerRegisterViewModel: BaseViewModel, ViewModelType { }) .disposed(by: disposeBag) - registerInOut() - } - - private func validateBirthYear(_ year: Int) -> Bool { - let currentYear: Int = Calendar.current.component(.year, from: Date()) - return (1900.. Bool { + let currentYear: Int = Calendar.current.component(.year, from: Date()) + return (1900..? var phoneNumberValidation: RxCocoa.Driver? var authNumberValidation: RxCocoa.Driver? + var loginValidation: RxCocoa.Driver? init( coordinator: PhoneNumberValidationForDeregisterCoordinator?,