diff --git a/Hyangyu/Hyangyu/Resources/Constants/URL.swift b/Hyangyu/Hyangyu/Resources/Constants/URL.swift index d2f5860..e13ae35 100644 --- a/Hyangyu/Hyangyu/Resources/Constants/URL.swift +++ b/Hyangyu/Hyangyu/Resources/Constants/URL.swift @@ -19,18 +19,22 @@ extension Const { static let signUpURL = "/user/signup" // 로그인 (POST) - static let signInURL = "/auth" + // 비밀번호 찾기(POST) + static let findPasswordURL = "/send-email" + // 비밀번호 변경 (POST) static let passwordURL = "/user/password" + // 인증번호 동일 확인 (DELETE) + static let checkCodeURL = "/authnum" + // MARK: - Saved - My Page Saved Service // 전시회 저장 (POST), 전시회 취소(DELETE), 전시회 조회 (GET), 카테고리 - 전시회(GET) static let displayURL = "/display" - // MARK: - My Page - User Service // 닉네임 변경 (POST) diff --git a/Hyangyu/Hyangyu/Sources/APIModels/Auth.swift b/Hyangyu/Hyangyu/Sources/APIModels/Auth.swift index 4012972..b0583f8 100644 --- a/Hyangyu/Hyangyu/Sources/APIModels/Auth.swift +++ b/Hyangyu/Hyangyu/Sources/APIModels/Auth.swift @@ -32,5 +32,3 @@ struct CodeData: Codable { struct EmailCheckData: Codable { let message: String } - - diff --git a/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordAPI.swift b/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordAPI.swift index 3fb1ccf..92a1d52 100644 --- a/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordAPI.swift +++ b/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordAPI.swift @@ -15,14 +15,16 @@ public class PasswordAPI { public init() { } - func putNewPassword(completion: @escaping (NetworkResult) -> Void, email: String, password: String) { - courseProvider.request(.putChangedPassword(email: email, password: password)) { (result) in + func postNewPassword(completion: @escaping (NetworkResult) -> Void, email: String, password: String) { + courseProvider.request(.postChangedPassword(email: email, password: password)) { (result) in + print(result) switch result { case .success(let response): + print("response 제대로 오는지 확인: ", response) let statusCode = response.statusCode let data = response.data - let networkResult = self.judgeChangePasswordStatus(by: statusCode, data) + let networkResult = self.judgeStatus(by: statusCode, data) completion(networkResult) case .failure(let err): @@ -31,13 +33,28 @@ public class PasswordAPI { } } - func getEmailCode(completion: @escaping (NetworkResult) -> Void, email: String) { - courseProvider.request(.getEmailCode(email: email)) { (result) in + func postEmailCode(completion: @escaping (NetworkResult) -> Void, email: String) { + courseProvider.request(.postEmailCode(email: email)) { (result) in switch result { case .success(let response): let statusCode = response.statusCode let data = response.data - let networkResult = self.judgeGetEmailCodeStatus(by: statusCode, data) + let networkResult = self.judgeStatus(by: statusCode, data) + completion(networkResult) + + case .failure(let err): + print(err) + } + } + } + + func checkCode(completion: @escaping (NetworkResult) -> Void, email: String, authNum: String) { + courseProvider.request(.checkCode(email: email, authNum: authNum)) { (result) in + switch result { + case .success(let response): + let statusCode = response.statusCode + let data = response.data + let networkResult = self.judgeStatus(by: statusCode, data) completion(networkResult) case .failure(let err): @@ -67,16 +84,16 @@ public class PasswordAPI { } } - private func judgeGetEmailCodeStatus(by statusCode: Int, _ data: Data) -> NetworkResult { - + private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult { let decoder = JSONDecoder() - guard let decodedData = try? decoder.decode(GenericResponse.self, from: data) else { + guard let decodedData = try? decoder.decode(GenericResponse.self, from: data) + else { return .pathErr } switch statusCode { case 200: - return .success(decodedData.data) + return .success(decodedData.message) case 400..<500: return .requestErr(decodedData.message) case 500: @@ -86,4 +103,3 @@ public class PasswordAPI { } } } - diff --git a/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordService.swift b/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordService.swift index 668044d..babc1bd 100644 --- a/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordService.swift +++ b/Hyangyu/Hyangyu/Sources/APIServices/AuthAPI/PasswordService.swift @@ -9,8 +9,10 @@ import Foundation import Moya enum PasswordService { - case putChangedPassword(email: String, password: String) - case getEmailCode(email: String) + case postChangedPassword(email: String, password: String) + case postEmailCode(email: String) + case checkCode(email: String, authNum: String) + } extension PasswordService: TargetType { @@ -20,19 +22,23 @@ extension PasswordService: TargetType { var path: String { switch self { - case .putChangedPassword(_, _): + case .postChangedPassword(_, _): return Const.URL.passwordURL - case .getEmailCode(let email): - return Const.URL.passwordURL + "/\(email)" + case .postEmailCode(let email): + return Const.URL.findPasswordURL + "/\(email)" + case .checkCode(let email, let authNum): + return Const.URL.checkCodeURL } } var method: Moya.Method { switch self { - case .putChangedPassword(_, _): - return .put - case .getEmailCode(_): - return .get + case .postChangedPassword(_, _): + return .post + case .postEmailCode(_): + return .post + case .checkCode(_, _): + return .delete } } @@ -42,14 +48,20 @@ extension PasswordService: TargetType { var task: Task { switch self { - case .putChangedPassword(let email, let password): + case .postChangedPassword(let email, let password): // body가 있는 request - JSONEncoding.default return .requestParameters(parameters: [ "email": email, + "username": "", "password": password ], encoding: JSONEncoding.default) - case .getEmailCode(_): + case .postEmailCode(_): return .requestPlain + case .checkCode(let email, let authNum): + return .requestParameters(parameters: [ + "email": email, + "authNum": authNum + ], encoding: JSONEncoding.default) } } @@ -59,4 +71,3 @@ extension PasswordService: TargetType { ] } } - diff --git a/Hyangyu/Hyangyu/Sources/AppDelegate.swift b/Hyangyu/Hyangyu/Sources/AppDelegate.swift index 915c428..92b1a11 100644 --- a/Hyangyu/Hyangyu/Sources/AppDelegate.swift +++ b/Hyangyu/Hyangyu/Sources/AppDelegate.swift @@ -11,19 +11,6 @@ import CoreData @main class AppDelegate: UIResponder, UIApplicationDelegate { - - // MARK: - Core Data - lazy var persistentContainer: NSPersistentContainer = { - // name: Core Data 만든 파일명 지정 - let container = NSPersistentContainer(name: "RecentSearchTerm") - container.loadPersistentStores(completionHandler: { (storeDescription, error) in - if let error = error { - fatalError("Unresolved error, \((error as NSError).userInfo)") - } - }) - return container - }() - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. diff --git a/Hyangyu/Hyangyu/Sources/AppModels/User.swift b/Hyangyu/Hyangyu/Sources/AppModels/User.swift index 4adff85..ad3becb 100644 --- a/Hyangyu/Hyangyu/Sources/AppModels/User.swift +++ b/Hyangyu/Hyangyu/Sources/AppModels/User.swift @@ -11,6 +11,8 @@ import UIKit class User { static let shared = User() + var email: String? var username: String? var profileImage: UIImage? + var password: String? } diff --git a/Hyangyu/Hyangyu/Sources/CustomTabBar/UIColor+RGB.swift b/Hyangyu/Hyangyu/Sources/CustomTabBar/UIColor+RGB.swift index d5d5d6f..51ad568 100644 --- a/Hyangyu/Hyangyu/Sources/CustomTabBar/UIColor+RGB.swift +++ b/Hyangyu/Hyangyu/Sources/CustomTabBar/UIColor+RGB.swift @@ -21,4 +21,3 @@ extension UIColor { } } } - diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.swift b/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.swift index a2e09a1..bb89e2e 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.swift +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.swift @@ -11,16 +11,18 @@ class FindPasswordViewController: UIViewController { // MARK: - Properties - let user = SignUpUser.shared + let user = User.shared var isResetCodeEnabled: Bool = false private var userResetCode: Int = 0 + private var isEmailRight: Bool = false + // MARK: - @IBOutlet Properties @IBOutlet weak var emailTextField: UITextField! @IBOutlet weak var emailTextFieldView: UIView! @IBOutlet weak var emailWarningLabel: UILabel! - - @IBOutlet weak var nextButton: UIButton! + + // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() initNavigationBar() @@ -30,6 +32,23 @@ class FindPasswordViewController: UIViewController { } // MARK: - Functions + private func addTarget() { + emailTextField.addTarget(self, action: #selector(self.activateEmailTextField), for: .editingDidBegin) + emailTextField.addTarget(self, action: #selector(self.inactivateEmailTextField), for: .editingDidEnd) + } + + // 텍스트 필드 확성화 + @objc private func activateEmailTextField() { + emailTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } + + // 텍스트 필드 비활성화 + @objc private func inactivateEmailTextField() { + + isEmailRight = checkEmail(email: emailTextField.text ?? "") + emailWarningLabel.isHidden = isEmailRight || !emailTextField.hasText ? true : false + emailTextFieldView.layer.borderColor = isEmailRight || !emailTextField.hasText ? UIColor.systemGray2.cgColor : UIColor.systemRed.cgColor + } private func initNavigationBar() { self.navigationController?.initWithBackButton() @@ -39,19 +58,17 @@ class FindPasswordViewController: UIViewController { emailTextField.delegate = self } - private func configureUI() { - emailTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) - nextButton.makeRounded(radius: 20) + emailTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray6.cgColor) + nextButton.makeRounded(radius: 12) emailWarningLabel.isHidden = true - nextButton.isEnabled = false } private func checkEmailFormat(email: String) { - if validateEmail(email: email) { + if checkEmail(email: email) { nextButton.isEnabled = true nextButton.alpha = 1.0 @@ -65,7 +82,7 @@ class FindPasswordViewController: UIViewController { } } - func validateEmail(email: String) -> Bool { + private func checkEmail(email: String) -> Bool { // Email 정규식 let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegEx) @@ -82,51 +99,45 @@ class FindPasswordViewController: UIViewController { nextButton.alpha = 0.3 } - func validateCode(code: String) -> Bool { - // Email 정규식 - let codeRegEx = "^[0-9]{4}$" - let codeTest = NSPredicate(format: "SELF MATCHES %@", codeRegEx) - return codeTest.evaluate(with: code) + // 화면 터치시 키보드 내림 + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + self.view.endEditing(true) } - private func checkCodeFormat(userInput: String) { - if validateCode(code: userInput) { - makeCompleteButtonEnable() - } else { - makeCompleteButtonDisable() - } - } + private func pushToNewPasswordViewController(email: String) { + let resetCodeViewController = ResetCodeViewController.loadFromNib() + resetCodeViewController.email = email + self.navigationController?.pushViewController(resetCodeViewController, animated: true) - - - private func pushToNewPasswordViewController() { - self.navigationController?.pushViewController(NewPasswordViewController.loadFromNib(), animated: true) } + @IBAction func touchNextButton(_ sender: Any) { + getCode() + } - } extension FindPasswordViewController: UITextFieldDelegate { func textFieldDidBeginEditing(_ textField: UITextField) { + emailWarningLabel.isHidden = true emailTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) } - // 실시간 - func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { - guard let text = textField.text else { - return false - } - checkEmailFormat(email: text) - return true - } +// func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { +// guard let text = textField.text else { +// return false +// } +// return true +// } - // 키보드 내렸을 때 (.co 등 때문에 추가) func textFieldDidEndEditing(_ textField: UITextField) { guard let text = textField.text else { return } - checkEmailFormat(email: text) + if text != "" { + checkEmailFormat(email: text) + } + emailTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray6.cgColor) } @@ -137,19 +148,23 @@ extension FindPasswordViewController { if let email = self.emailTextField.text { - PasswordAPI.shared.getEmailCode(completion: { (result) in + PasswordAPI.shared.postEmailCode(completion: { (result) in switch result { case .success(let code): - if let data = code as? CodeData { + if let data = code as? String { self.emailWarningLabel.isHidden = true self.user.email = email + print("data.message: \(data)") + self.emailWarningLabel.text = "\(data)" + self.pushToNewPasswordViewController(email: email) } case .requestErr(let message): self.emailWarningLabel.isHidden = false if let message = message as? String { self.emailWarningLabel.text = "\(message)" } + self.pushToNewPasswordViewController(email: email) case .pathErr: print(".pathErr") case .serverErr: diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.xib b/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.xib index 8335ae9..83f0758 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.xib +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/FindPassword/FindPasswordViewController.xib @@ -1,8 +1,9 @@ - + - + + @@ -24,7 +25,7 @@ - + diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/MyPage/ProfileEditViewController.swift b/Hyangyu/Hyangyu/Sources/ViewControllers/MyPage/ProfileEditViewController.swift index 0b3b1f2..b6fc322 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/MyPage/ProfileEditViewController.swift +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/MyPage/ProfileEditViewController.swift @@ -9,7 +9,7 @@ import UIKit import Then -protocol ProfileEditViewControllerDelegate: class { +protocol ProfileEditViewControllerDelegate: AnyObject { func setUpdate(data: MyPageResponse) } @@ -19,7 +19,6 @@ struct ProfileEditViewControllerViewModel { } - final class ProfileEditViewController: UIViewController { // MARK: - Properties @@ -47,7 +46,6 @@ final class ProfileEditViewController: UIViewController { @IBOutlet weak var countingLabel: UILabel! - private let imageShadowView = UIView().then { $0.layer.shadowOffset = CGSize(width: 0, height: 0) $0.layer.shadowOpacity = 0.2 @@ -55,7 +53,6 @@ final class ProfileEditViewController: UIViewController { $0.layer.shadowColor = UIColor.gray.cgColor } - weak var delegate: ProfileEditViewControllerDelegate? private var viewModel: ProfileEditViewControllerViewModel = ProfileEditViewControllerViewModel(profileImage: UIImage(), userName: "") @@ -90,7 +87,6 @@ final class ProfileEditViewController: UIViewController { userProfileImageView.clipsToBounds = true } - private func setDelegation() { userNameTextField.delegate = self let tapGesture = UITapGestureRecognizer(target: self, action: #selector(touchToPickImage)) @@ -144,7 +140,6 @@ final class ProfileEditViewController: UIViewController { // MARK: - @IBAction - @IBAction func didTapCancel(_ sender: Any) { dismiss(animated: true, completion: nil) } @@ -219,11 +214,7 @@ final class ProfileEditViewController: UIViewController { @objc func touchToPickImage() { actionSheetAlert() } - - - - - + private func actionSheetAlert() { let imagePickerController = UIImagePickerController() imagePickerController.delegate = self @@ -268,12 +259,11 @@ final class ProfileEditViewController: UIViewController { self.viewModel = viewModel } - } // MARK: - UIImagePickerControllerDelegate, UINavigationControllerDelegatenil extension ProfileEditViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { - func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { var newImage: UIImage? = nil diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.swift b/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.swift index 023ef09..5840f52 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.swift +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.swift @@ -8,22 +8,232 @@ import UIKit class NewPasswordViewController: UIViewController { - + + var user = User.shared + private var isPasswordRight: Bool = false + private var isConfirmPasswordRight: Bool = false + + @IBOutlet weak var passwordTextFieldView: UIView! + @IBOutlet weak var passwordTextField: UITextField! + @IBOutlet weak var passwordWarningLabel: UILabel! + + @IBOutlet weak var confirmPasswordTextFieldView: UIView! + @IBOutlet weak var confirmPasswordTextField: UITextField! + @IBOutlet weak var confirmPasswordWarningLabel: UILabel! + + @IBOutlet weak var passwordSecureButton: UIButton! + @IBOutlet weak var confirmPasswordSecureButton: UIButton! + @IBOutlet weak var confirmButton: UIButton! + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + + initNavigationBar() + configureUI() + setDelegation() + } + + private func initNavigationBar() { + self.navigationController?.initWithBackButton() + } + + private func configureUI() { + [passwordTextFieldView, confirmPasswordTextFieldView].forEach({$0?.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray6.cgColor) }) + [passwordWarningLabel, confirmPasswordWarningLabel].forEach({$0?.isHidden = true }) + + confirmButtonDisable() + confirmButton.makeRounded(radius: 12) + + } + + // MARK: - Functions + private func checkTextField() { + // 입력 중 일때 + passwordTextField.addTarget(self, action: #selector(self.checkPasswordTextField), for: .editingChanged) + confirmPasswordTextField.addTarget(self, action: #selector(self.checkConfirmPasswordTextField), for: .editingChanged) + + } + + // 비밀번호 텍필 값 바뀔 때 + @objc private func checkPasswordTextField() { + // 비밀번호 + let passwordCount = passwordTextField.text?.count ?? 0 + if passwordCount > 11 { + passwordTextField.deleteBackward() + } + isPasswordRight = checkPassword(password: passwordTextField.text ?? "") + passwordWarningLabel.isHidden = isPasswordRight || !passwordTextField.hasText ? true : false + passwordTextFieldView.layer.borderColor = isPasswordRight || !passwordTextField.hasText ? UIColor.systemGray2.cgColor : UIColor.systemRed.cgColor + + // 비밀번호 확인 텍필 + isConfirmPasswordRight = checkConfirmPassword(input: passwordTextField.text ?? "") + confirmPasswordWarningLabel.isHidden = isConfirmPasswordRight || !confirmPasswordTextField.hasText ? true : false + confirmPasswordTextFieldView.layer.borderColor = isConfirmPasswordRight || !confirmPasswordTextField.hasText ? UIColor.systemGray2.cgColor : UIColor.systemRed.cgColor + } + + // 비밀번호 확인 텍필 값 바뀔 떄 + @objc private func checkConfirmPasswordTextField() { + isConfirmPasswordRight = checkConfirmPassword(input: passwordTextField.text ?? "") + confirmPasswordWarningLabel.isHidden = isConfirmPasswordRight || !confirmPasswordTextField.hasText ? true : false + confirmPasswordTextFieldView.layer.borderColor = isConfirmPasswordRight || !confirmPasswordTextField.hasText ? UIColor.systemGray2.cgColor : UIColor.systemRed.cgColor + } + + @IBAction func updateCurrentStatus(_ sender: Any) { + passwordTextField.isSecureTextEntry.toggle() + if passwordTextField.isSecureTextEntry { + passwordSecureButton.setImage(UIImage(systemName: "eye"), for: .normal) + } else { + passwordSecureButton.setImage(UIImage(systemName: "eye.slash"), for: .normal) + } + } + + @IBAction func updateConfirmStatus(_ sender: UIButton) { + confirmPasswordTextField.isSecureTextEntry.toggle() + if confirmPasswordTextField.isSecureTextEntry { + confirmPasswordSecureButton.setImage(UIImage(systemName: "eye"), for: .normal) + } else { + confirmPasswordSecureButton.setImage(UIImage(systemName: "eye.slash"), for: .normal) + } + } + + // 화면 터치시 키보드 내림 + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + self.view.endEditing(true) + } + + private func checkConfirmPassword (input: String) -> Bool { + return passwordTextField.text == confirmPasswordTextField.text + } + + private func setDelegation() { + passwordTextField.delegate = self + confirmPasswordTextField.delegate = self + } + + private func confirmButtonEnable() { + confirmButton.isEnabled = true + confirmButton.alpha = 1.0 + } + + private func confirmButtonDisable() { + confirmButton.isEnabled = false + confirmButton.alpha = 0.3 + } + + private func showFormatError() { + passwordWarningLabel.isHidden = false + passwordWarningLabel.text = "6~12자리의 영문, 숫자, 특수문자만 사용 가능합니다" + passwordWarningLabel.textColor = UIColor.systemRed + confirmButtonDisable() + } + + private func hideFormatError() { + passwordWarningLabel.isHidden = false + passwordWarningLabel.text = "사용 가능한 비밀번호입니다" + passwordWarningLabel.textColor = UIColor.systemGreen + confirmButtonDisable() + } + + private func checkPasswordSameness() { + if passwordTextField.text == confirmPasswordTextField.text { + confirmPasswordWarningLabel.isHidden = false + confirmPasswordWarningLabel.text = "비밀번호가 일치합니다" + confirmPasswordWarningLabel.textColor = .systemGreen + confirmButtonEnable() + } else { + confirmPasswordWarningLabel.isHidden = false + confirmPasswordWarningLabel.text = "비밀번호가 일치하지 않습니다." + confirmPasswordWarningLabel.textColor = .systemRed + confirmButtonDisable() + } + } + + // 패스워드 정규식 체크 + private func checkPassword(password: String) -> Bool { + let passwordRegEx = "[A-Z0-9a-z!@#$%^&*()_+=-]{6,12}" + let passwordText = NSPredicate(format: "SELF MATCHES %@", passwordRegEx) + return passwordText.evaluate(with: password) + } + + @IBAction func touchCompleteButton(_ sender: UIButton) { + postNewPassword() + } + + func popToRootViewController() { + self.navigationController?.popToRootViewController(animated: true) + } +} - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. +extension NewPasswordViewController: UITextFieldDelegate { + func textFieldDidBeginEditing(_ textField: UITextField) { + + if textField == passwordTextField { + passwordTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } else if textField == confirmPasswordTextField { + confirmPasswordTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } + } - */ + + func textFieldDidEndEditing(_ textField: UITextField) { + + if textField == passwordTextField { + passwordTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } else if textField == confirmPasswordTextField { + confirmPasswordTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } + + guard let password = passwordTextField.text else { + return + } + + if password != "" { + if checkPassword(password: password) { + if confirmPasswordTextField.text != "" { + checkPasswordSameness() + } else { + hideFormatError() + } + } else { + showFormatError() + } + } else { + passwordWarningLabel.isHidden = true + } + } +} +extension NewPasswordViewController { + func postNewPassword() { + guard let password = passwordTextField.text else { + return + } + user.password = password + + guard let email = user.email else { + return + } + + PasswordAPI.shared.postNewPassword(completion: { (response) in + switch response { + case .success(let data): + if let data = data as? String { + self.showToast(message: data) + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + self.dismiss(animated: true) + } + } + self.popToRootViewController() + case .requestErr(let message): + print("requestErr", message) + case .pathErr: + print("pathErr") + case .serverErr: + print("serverErr") + case .networkFail: + print("networkFail") + } + }, email: email, password: password) + } } diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.xib b/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.xib index 852275c..2dade29 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.xib +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/NewPassword/NewPasswordViewController.xib @@ -1,8 +1,9 @@ - + - + + @@ -11,6 +12,15 @@ + + + + + + + + + @@ -19,40 +29,52 @@ - + + - - - + + - - - + - - + + + + + - + diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.swift b/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.swift index 68ac84d..dd1d8f9 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.swift +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.swift @@ -8,22 +8,158 @@ import UIKit class ResetCodeViewController: UIViewController { - + + // MARK: - Properties + var email: String? // 이메일 + + // MARK: - @IBOutlet Properties + + @IBOutlet weak var codeTextFieldView: UIView! + @IBOutlet weak var codeTextField: UITextField! + @IBOutlet weak var warningLabel: UILabel! + @IBOutlet weak var completeButton: UIButton! + + // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + + initNavigationBar() + setDelegation() + configureUI() + } + + // MARK: - Functions + private func addTarget() { + codeTextField.addTarget(self, action: #selector(self.activateCodeTextField), for: .editingDidBegin) + codeTextField.addTarget(self, action: #selector(self.inactivateCodeTextField), for: .editingDidEnd) + codeTextField.addTarget(self, action: #selector(self.activateCompleteButton), for: .editingChanged) + } + + // 텍스트 필드 확성화 + @objc private func activateCodeTextField() { + codeTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + } + + // 텍스트 필드 비활성화 + @objc private func inactivateCodeTextField() { + codeTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray6.cgColor) + } + + // 버튼 활성화 + @objc private func activateCompleteButton() { + completeButton.isEnabled = codeTextField.hasText + completeButton.alpha = 1.0 + } + + private func initNavigationBar() { + self.navigationController?.initWithBackButton() + } + + private func setDelegation() { + self.codeTextField.delegate = self + } + + private func configureUI() { + codeTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray6.cgColor) + completeButton.makeRounded(radius: 12) + warningLabel.isHidden = true + makeCompleteButtonDisable() + } + + private func pushToNewPasswordViewController() { + self.navigationController?.pushViewController(NewPasswordViewController.loadFromNib(), animated: true) + } + + private func makeCompleteButtonEnable() { + completeButton.isEnabled = true + completeButton.alpha = 1.0 + } + + private func makeCompleteButtonDisable() { + completeButton.isEnabled = false + completeButton.alpha = 0.3 + } + + func validateCode(code: String) -> Bool { + // Email 정규식 + let codeRegEx = "^[a-z0-9+]{6}$" + let codeTest = NSPredicate(format: "SELF MATCHES %@", codeRegEx) + return codeTest.evaluate(with: code) + } + + private func checkCodeFormat(userInput: String) { + if validateCode(code: userInput) { + makeCompleteButtonEnable() + } else { + makeCompleteButtonDisable() + } + } + + @IBAction func touchCompleteButton(_ sender: Any) { + sendCode() + } + + // 화면 터치시 키보드 내림 + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + self.view.endEditing(true) + } + + private func pushToNewPasswordViewController(email: String) { + let newPasswordViewController = NewPasswordViewController.loadFromNib() + self.navigationController?.pushViewController(newPasswordViewController, animated: true) + } + +} - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. +// MARK: - UITextFieldDelegate +extension ResetCodeViewController: UITextFieldDelegate { + func textFieldDidEndEditing(_ textField: UITextField) { + guard let text = textField.text else { + return + } + checkCodeFormat(userInput: text) + } + + func textFieldDidBeginEditing(_ textField: UITextField) { + warningLabel.isHidden = true + codeTextFieldView.makeRoundedWithBorder(radius: 12, color: UIColor.systemGray2.cgColor) + completeButton.isEnabled = true } - */ + + // Return 눌렀을 시 키보드 내리기 + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} +extension ResetCodeViewController { + func sendCode() { + guard let code = codeTextField.text else { + return + } + + PasswordAPI.shared.checkCode(completion: { response in + switch response { + case .success(let data): + self.pushToNewPasswordViewController() + case .requestErr(let message): + if let message = message as? String { + print(message) + self.showToast(message: message) + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + self.dismiss(animated: true) + } + } + print("requestErr", message) + case .pathErr: + print("pathErr") + case .serverErr: + print("serverErr") + case .networkFail: + print("networkFail") + } + }, email: email ?? "", authNum: code) + } } diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.xib b/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.xib index feec7d8..ede97b3 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.xib +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/ResetCode/ResetCodeViewController.xib @@ -1,8 +1,9 @@ - + - + + @@ -11,7 +12,11 @@ + + + + @@ -28,21 +33,21 @@ - + - + - + - - - - + + + + diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/SignIn/SignInViewController.xib b/Hyangyu/Hyangyu/Sources/ViewControllers/SignIn/SignInViewController.xib index 5fa24ff..9a8ad68 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/SignIn/SignInViewController.xib +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/SignIn/SignInViewController.xib @@ -1,8 +1,9 @@ - + - + + diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.swift b/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.swift index e58c8b3..d20db5f 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.swift +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.swift @@ -92,8 +92,6 @@ class SignUpViewController: UIViewController { // 버튼 활성화 조건 [emailTextField, passwordTextField, confirmPasswordTextField, nicknameTextField].forEach {$0.addTarget(self, action: #selector(self.activateSignUpButton), for: .editingChanged)} - - } // 이메일 정규식 체크 diff --git a/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.xib b/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.xib index 5b99c8a..66caa57 100644 --- a/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.xib +++ b/Hyangyu/Hyangyu/Sources/ViewControllers/SignUp/SignUpViewController.xib @@ -1,8 +1,9 @@ - + - + + diff --git a/Hyangyu/Hyangyu/Sources/Views/HeaderView.swift b/Hyangyu/Hyangyu/Sources/Views/HeaderView.swift index e3c3172..cc61856 100644 --- a/Hyangyu/Hyangyu/Sources/Views/HeaderView.swift +++ b/Hyangyu/Hyangyu/Sources/Views/HeaderView.swift @@ -6,6 +6,7 @@ // import UIKit + import Kingfisher import Then import SnapKit @@ -58,7 +59,6 @@ class HeaderView: UIView { weak var delegate: HeaderViewDelegate? - func configureUI() { addSubview(profileImageView) addSubview(userNameLabel) @@ -66,7 +66,6 @@ class HeaderView: UIView { buttonStackView.addArrangedSubview(profileEditButton) buttonStackView.addArrangedSubview(myReviewButton) - profileImageView.snp.makeConstraints { $0.top.equalTo(safeAreaInsets.top).offset(110) $0.leading.equalTo(safeAreaInsets.left).offset(20)