From 32f9ddaa7dc38d09091278f3f127cb8a01c99a52 Mon Sep 17 00:00:00 2001 From: Bilal Date: Fri, 3 May 2024 20:27:54 +0530 Subject: [PATCH] - Made the forget password UI. - Made login view. - Continue the flow from onboarding. - added the flow from login-> create account and forget password. --- README.md | 2 +- WOKA.xcodeproj/project.pbxproj | 42 +- .../Base.lproj/AuthenticationSB.storyboard | 543 +++++++++++++++++- WOKA/Authentication/Controller/LoginVC.swift | 67 ++- .../Controller/NewPasswordVC.swift | 60 +- WOKA/Authentication/Controller/OTPVC.swift | 20 +- .../Controller/ResetPassUserNameVC.swift | 39 +- .../Controller/SelectAvatarVC.swift | 4 + .../View/SelectAvatarCell.swift | 2 +- WOKA/Authentication/View/SelectAvatarCell.xib | 2 +- WOKA/Authentication/ViewModel/LoginVM.swift | 34 +- .../ViewModel/SelectAvatarVM.swift | 4 + WOKA/Constants K/StoryBoard.swift | 1 + WOKA/Constants K/StoryBoardID.swift | 7 + .../UIElements Helper/TextFieldImage.swift | 5 +- .../UIElements Helper/TextFieldPassword.swift | 27 +- WOKA/Helpers/Validations/ValidatorClass.swift | 60 +- WOKA/Home/Home.storyboard | 7 +- .../Controller/OnBoardVC.swift | 3 + .../Controller/SplashVC.swift | 60 +- 20 files changed, 906 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 6a5b68b..b3a910c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ This Library consist of all Reusable Modules For iOS with language **SWIFT**. -[![Platform](https://img.shields.io/badge/Swift-Compatible-52EC18)](https://github.com/WdiplCodeRepo/IOS/tree/main/Authentication) +[![Platform](https://img.shields.io/badge/Swift-Compatible-52EC18)](https://developer.apple.com/swift/) ## Usage diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 879f01d..f749848 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -74,6 +74,14 @@ 9C56E8462BDBEE6400E4CA14 /* EmailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C56E8452BDBEE6400E4CA14 /* EmailVC.swift */; }; 9C56E8482BDBEFAB00E4CA14 /* AssetColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C56E8472BDBEFAB00E4CA14 /* AssetColor.swift */; }; 9C56E84B2BDBF03F00E4CA14 /* AuthenticationSB.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E84A2BDBF03F00E4CA14 /* AuthenticationSB.storyboard */; }; + 9CBCB29B2BE4D614007D7934 /* LoginVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB29A2BE4D614007D7934 /* LoginVC.swift */; }; + 9CBCB29D2BE4D6BB007D7934 /* LoginVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB29C2BE4D6BB007D7934 /* LoginVM.swift */; }; + 9CBCB29F2BE4E13A007D7934 /* ValidatorClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB29E2BE4E13A007D7934 /* ValidatorClass.swift */; }; + 9CBCB2A12BE4E50A007D7934 /* TextFieldPassword.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB2A02BE4E50A007D7934 /* TextFieldPassword.swift */; }; + 9CBCB2A32BE50C95007D7934 /* ResetPassUserNameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB2A22BE50C95007D7934 /* ResetPassUserNameVC.swift */; }; + 9CBCB2A52BE50D49007D7934 /* NewPasswordVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB2A42BE50D49007D7934 /* NewPasswordVC.swift */; }; + 9CBCB2A82BE5105A007D7934 /* Home.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9CBCB2A72BE5105A007D7934 /* Home.storyboard */; }; + 9CBCB2AA2BE51A52007D7934 /* HomeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBCB2A92BE51A52007D7934 /* HomeVC.swift */; }; 9CDC343C2BDBBC6B00093089 /* SelectAgeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDC343B2BDBBC6B00093089 /* SelectAgeVC.swift */; }; 9CDCE1452BDB9B9A003FEF11 /* OnBoardMainSound.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 9CDCE1442BDB9B9A003FEF11 /* OnBoardMainSound.m4a */; }; /* End PBXBuildFile section */ @@ -170,6 +178,14 @@ 9C56E8452BDBEE6400E4CA14 /* EmailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailVC.swift; sourceTree = ""; }; 9C56E8472BDBEFAB00E4CA14 /* AssetColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetColor.swift; sourceTree = ""; }; 9C56E8492BDBF03F00E4CA14 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/AuthenticationSB.storyboard; sourceTree = ""; }; + 9CBCB29A2BE4D614007D7934 /* LoginVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginVC.swift; sourceTree = ""; }; + 9CBCB29C2BE4D6BB007D7934 /* LoginVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginVM.swift; sourceTree = ""; }; + 9CBCB29E2BE4E13A007D7934 /* ValidatorClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorClass.swift; sourceTree = ""; }; + 9CBCB2A02BE4E50A007D7934 /* TextFieldPassword.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldPassword.swift; sourceTree = ""; }; + 9CBCB2A22BE50C95007D7934 /* ResetPassUserNameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPassUserNameVC.swift; sourceTree = ""; }; + 9CBCB2A42BE50D49007D7934 /* NewPasswordVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPasswordVC.swift; sourceTree = ""; }; + 9CBCB2A72BE5105A007D7934 /* Home.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Home.storyboard; sourceTree = ""; }; + 9CBCB2A92BE51A52007D7934 /* HomeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeVC.swift; sourceTree = ""; }; 9CDC343B2BDBBC6B00093089 /* SelectAgeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectAgeVC.swift; sourceTree = ""; }; 9CDCE1412BDB94BA003FEF11 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Main.strings; sourceTree = ""; }; 9CDCE1422BDB94BD003FEF11 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; @@ -226,6 +242,7 @@ children = ( 5202AB002BDFA7900043B7BD /* EmailValidation.swift */, 52D774EE2BDFC50D001D87DE /* StringValidations.swift */, + 9CBCB29E2BE4E13A007D7934 /* ValidatorClass.swift */, ); path = Validations; sourceTree = ""; @@ -255,14 +272,15 @@ 523ED25C2BDA2BC700CFED02 /* WOKA */ = { isa = PBXGroup; children = ( + 9CBCB2A62BE5104F007D7934 /* Home */, 52C6E01F2BE3ADD800E22D59 /* Default Enum */, 9C56E83E2BDBE4FB00E4CA14 /* Authentication */, + 523ED28E2BDA372C00CFED02 /* OnBoarding Module */, 9C27E1612BDB6F0F00EC1DA9 /* Main */, 9C27E15E2BDB6E4F00EC1DA9 /* Localized Module */, 52C8B0552BDA57CE003B51D0 /* Constants K */, 52C8B0512BDA4B51003B51D0 /* Helpers */, 523ED2932BDA3D0100CFED02 /* Assets */, - 523ED28E2BDA372C00CFED02 /* OnBoarding Module */, 523ED2682BDA2BC900CFED02 /* LaunchScreen.storyboard */, 523ED26B2BDA2BC900CFED02 /* Info.plist */, ); @@ -392,6 +410,7 @@ 5202AAFD2BDF90590043B7BD /* TextFieldImage.swift */, 52663FF42BDFAB830001D8CE /* TextFieldErrorView.swift */, 52663FFA2BDFB1700001D8CE /* TextFieldShadow.swift */, + 9CBCB2A02BE4E50A007D7934 /* TextFieldPassword.swift */, ); path = "UIElements Helper"; sourceTree = ""; @@ -484,6 +503,7 @@ 5272FCE42BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift */, 52CA28FB2BE11A0400708B49 /* UserIntrestVM.swift */, 52C6E0282BE3B52500E22D59 /* SelectAvatarVM.swift */, + 9CBCB29C2BE4D6BB007D7934 /* LoginVM.swift */, ); path = ViewModel; sourceTree = ""; @@ -496,10 +516,22 @@ 5272FCE22BDFDB05000ECB1D /* UserDetailsRegisterVC.swift */, 52CA28F92BE119F500708B49 /* UserIntrestVC.swift */, 52C6E0222BE3B3E300E22D59 /* SelectAvatarVC.swift */, + 9CBCB29A2BE4D614007D7934 /* LoginVC.swift */, + 9CBCB2A22BE50C95007D7934 /* ResetPassUserNameVC.swift */, + 9CBCB2A42BE50D49007D7934 /* NewPasswordVC.swift */, ); path = Controller; sourceTree = ""; }; + 9CBCB2A62BE5104F007D7934 /* Home */ = { + isa = PBXGroup; + children = ( + 9CBCB2A72BE5105A007D7934 /* Home.storyboard */, + 9CBCB2A92BE51A52007D7934 /* HomeVC.swift */, + ); + path = Home; + sourceTree = ""; + }; 9CDCE1432BDB9B64003FEF11 /* Sounds */ = { isa = PBXGroup; children = ( @@ -623,6 +655,7 @@ 9C27E1732BDB86B600EC1DA9 /* OnBoardCell.xib in Resources */, 9CDCE1452BDB9B9A003FEF11 /* OnBoardMainSound.m4a in Resources */, 9C56E84B2BDBF03F00E4CA14 /* AuthenticationSB.storyboard in Resources */, + 9CBCB2A82BE5105A007D7934 /* Home.storyboard in Resources */, 52C8B0632BDA6993003B51D0 /* Localizable.strings in Resources */, 9C56E8382BDBC3F000E4CA14 /* Exo2-ExtraBold.ttf in Resources */, 9C56E8372BDBC3F000E4CA14 /* Exo2-Thin.ttf in Resources */, @@ -726,16 +759,23 @@ 52C6E01B2BE383C000E22D59 /* YourIntrestCell.swift in Sources */, 523ED25E2BDA2BC700CFED02 /* AppDelegate.swift in Sources */, 52D774ED2BDFC13F001D87DE /* OTPVM.swift in Sources */, + 9CBCB2A32BE50C95007D7934 /* ResetPassUserNameVC.swift in Sources */, + 9CBCB2A52BE50D49007D7934 /* NewPasswordVC.swift in Sources */, + 9CBCB29F2BE4E13A007D7934 /* ValidatorClass.swift in Sources */, + 9CBCB29B2BE4D614007D7934 /* LoginVC.swift in Sources */, 9C56E83B2BDBC6E600E4CA14 /* SelectAgeVM.swift in Sources */, 52CA28FA2BE119F500708B49 /* UserIntrestVC.swift in Sources */, 9C27E16B2BDB774D00EC1DA9 /* CarouselData.swift in Sources */, 523ED2602BDA2BC700CFED02 /* SceneDelegate.swift in Sources */, + 9CBCB2AA2BE51A52007D7934 /* HomeVC.swift in Sources */, 52D774E92BDFBDA4001D87DE /* AuthenticationStringConstant.swift in Sources */, 9C27E1672BDB706700EC1DA9 /* StoryBoard.swift in Sources */, 52C8B0692BDA6E1E003B51D0 /* LocalizedEnum.swift in Sources */, 52C6E01E2BE3847F00E22D59 /* BorderView.swift in Sources */, 52C8B0742BDA7626003B51D0 /* OnBoardVC.swift in Sources */, + 9CBCB2A12BE4E50A007D7934 /* TextFieldPassword.swift in Sources */, 9C56E8482BDBEFAB00E4CA14 /* AssetColor.swift in Sources */, + 9CBCB29D2BE4D6BB007D7934 /* LoginVM.swift in Sources */, 5272FCE52BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift in Sources */, 9C27E1652BDB6FBC00EC1DA9 /* StoryBoardID.swift in Sources */, 9C27E1722BDB86B600EC1DA9 /* OnBoardCell.swift in Sources */, diff --git a/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard b/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard index cb0e816..93f4fa9 100644 --- a/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard +++ b/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard @@ -13,6 +13,9 @@ Exo2-Bold + + Exo2-ExtraBold + Exo2-Medium @@ -748,6 +751,7 @@ Sent to Your Parent’s Email + @@ -770,37 +774,568 @@ Sent to Your Parent’s Email + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + + + + + + + + + + - + - + + + + diff --git a/WOKA/Authentication/Controller/LoginVC.swift b/WOKA/Authentication/Controller/LoginVC.swift index e0c7339..a411cf5 100644 --- a/WOKA/Authentication/Controller/LoginVC.swift +++ b/WOKA/Authentication/Controller/LoginVC.swift @@ -9,21 +9,64 @@ import UIKit class LoginVC: UIViewController { + @IBOutlet weak var loginBtn: LocalisedElementsButton! + @IBOutlet weak var createAccountBtn: LocalisedElementsButton! + @IBOutlet weak var userNameTF: TextFieldShadow! + @IBOutlet weak var passwordTF: TextFieldShadow! + @IBOutlet weak var passwordStack: UIStackView! + @IBOutlet weak var passwordEyeBtn: UIButton! + + var vm = LoginVM() + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + vm.vc = self + vm.initView() } - - /* - // 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. + @IBAction func loginBtnTapped(_ sender: LocalisedElementsButton) { + } + + @IBAction func createAccountBtnTapped(_ sender: LocalisedElementsButton) { + let sb = UIStoryboard(name: K.StoryBoard.main, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.OnBoarding.selectAgeVC) as! SelectAgeVC + self.navigationController?.pushViewController(vc, animated: true) + } + + @IBAction func continueGuestBtnTapped(_ sender: UIButton) { + } + + @IBAction func forgotPasswordBtnTapped(_ sender: UIButton) { + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.resetPassUserNameVC) as! ResetPassUserNameVC + self.navigationController?.pushViewController(vc, animated: true) + } +} + + +// MARK: - Textfield Delegate + +extension LoginVC : UITextFieldDelegate{ + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + switch textField{ + case passwordTF: + let currentString = (textField.text ?? "") as NSString + let newString = currentString.replacingCharacters(in: range, with: string) + newString.count == 0 ? (textField.rightView?.isHidden = true) : (textField.rightView?.isHidden = false) + return ValidatorClass.sharedInstanec.limitCharacter(length: 16,textField, shouldChangeCharactersIn: range, replacementString: string) + default: + return true + } + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + switch textField{ + case passwordTF: + self.view.endEditing(true) + default: + break + } + return true } - */ - } diff --git a/WOKA/Authentication/Controller/NewPasswordVC.swift b/WOKA/Authentication/Controller/NewPasswordVC.swift index 9982325..b58a24a 100644 --- a/WOKA/Authentication/Controller/NewPasswordVC.swift +++ b/WOKA/Authentication/Controller/NewPasswordVC.swift @@ -9,21 +9,57 @@ import UIKit class NewPasswordVC: UIViewController { + @IBOutlet weak var enterNewPasswordTF: TextFieldShadow! + @IBOutlet weak var confirmPassTF: TextFieldShadow! + @IBOutlet weak var nextBtn: LocalisedElementsButton! + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + initView() + enterNewPasswordTF.enablePasswordToggle() + confirmPassTF.enablePasswordToggle() + enterNewPasswordTF.delegate = self + confirmPassTF.delegate = self } - - /* - // 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. + func initView(){ + enterNewPasswordTF.roundCorner() + confirmPassTF.roundCorner() + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + nextBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + } + + @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { + + } +} + +// MARK: - Textfield Delegate + +extension NewPasswordVC : UITextFieldDelegate{ + + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + switch textField{ + case enterNewPasswordTF,confirmPassTF: + let currentString = (textField.text ?? "") as NSString + let newString = currentString.replacingCharacters(in: range, with: string) + newString.count == 0 ? (textField.rightView?.isHidden = true) : (textField.rightView?.isHidden = false) + return ValidatorClass.sharedInstanec.limitCharacter(length: 16,textField, shouldChangeCharactersIn: range, replacementString: string) + default: + return true + } + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + switch textField{ + case enterNewPasswordTF: + self.confirmPassTF.becomeFirstResponder() + case confirmPassTF: + self.view.endEditing(true) + default: + break + } + return true } - */ - } diff --git a/WOKA/Authentication/Controller/OTPVC.swift b/WOKA/Authentication/Controller/OTPVC.swift index dfde471..145c805 100644 --- a/WOKA/Authentication/Controller/OTPVC.swift +++ b/WOKA/Authentication/Controller/OTPVC.swift @@ -7,6 +7,11 @@ import UIKit +enum NavigateToVC{ + case newPass + case registeration +} + class OTPVC : UIViewController{ @IBOutlet weak var wokaLogoTopConstriant: NSLayoutConstraint! @@ -22,6 +27,7 @@ class OTPVC : UIViewController{ @IBOutlet weak var requestThemLabel: LocalisedElementsLabel! var vm = OTPVM() + var navigateCheck = NavigateToVC.registeration override func viewDidLoad() { super.viewDidLoad() @@ -42,9 +48,17 @@ class OTPVC : UIViewController{ // MARK: - Button Tap Handler @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { - let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) - let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.userDetailsRegisterVC) as! UserDetailsRegisterVC - self.navigationController?.pushViewController(vc, animated: true) + switch self.navigateCheck{ + case .newPass: + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.newPasswordVC) as! NewPasswordVC + self.navigationController?.pushViewController(vc, animated: true) + case .registeration: + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.userDetailsRegisterVC) as! UserDetailsRegisterVC + self.navigationController?.pushViewController(vc, animated: true) + } + } } diff --git a/WOKA/Authentication/Controller/ResetPassUserNameVC.swift b/WOKA/Authentication/Controller/ResetPassUserNameVC.swift index 1f603b2..1bffde7 100644 --- a/WOKA/Authentication/Controller/ResetPassUserNameVC.swift +++ b/WOKA/Authentication/Controller/ResetPassUserNameVC.swift @@ -9,21 +9,36 @@ import UIKit class ResetPassUserNameVC: UIViewController { + @IBOutlet weak var usernameTF: TextFieldShadow! + @IBOutlet weak var nextBtn: LocalisedElementsButton! + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + initView() } - - /* - // 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. + func initView(){ + usernameTF.roundCorner() + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + nextBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(false, animated: animated) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + navigationController?.setNavigationBarHidden(true, animated: animated) + } + + + @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.oTPVC) as! OTPVC + vc.navigateCheck = .newPass + self.navigationController?.pushViewController(vc, animated: true) } - */ - } diff --git a/WOKA/Authentication/Controller/SelectAvatarVC.swift b/WOKA/Authentication/Controller/SelectAvatarVC.swift index d1ea4e4..f336145 100644 --- a/WOKA/Authentication/Controller/SelectAvatarVC.swift +++ b/WOKA/Authentication/Controller/SelectAvatarVC.swift @@ -10,6 +10,7 @@ import UIKit class SelectAvatarVC: UIViewController { @IBOutlet weak var collectionView: UICollectionView! + @IBOutlet weak var nextBtn: LocalisedElementsButton! var vm = SelectAvatarVM() @@ -28,6 +29,9 @@ class SelectAvatarVC: UIViewController { super.viewWillDisappear(animated) navigationController?.setNavigationBarHidden(true, animated: animated) } + + @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { + } } // MARK: - CollectionView Delegate diff --git a/WOKA/Authentication/View/SelectAvatarCell.swift b/WOKA/Authentication/View/SelectAvatarCell.swift index 7584b5f..882d074 100644 --- a/WOKA/Authentication/View/SelectAvatarCell.swift +++ b/WOKA/Authentication/View/SelectAvatarCell.swift @@ -18,7 +18,7 @@ class SelectAvatarCell: UICollectionViewCell { } override func layoutSubviews() { - self.outerView.roundCorner() + self.roundCorner() } func setData(){ diff --git a/WOKA/Authentication/View/SelectAvatarCell.xib b/WOKA/Authentication/View/SelectAvatarCell.xib index 0f926c9..37e5463 100644 --- a/WOKA/Authentication/View/SelectAvatarCell.xib +++ b/WOKA/Authentication/View/SelectAvatarCell.xib @@ -11,7 +11,7 @@ - + diff --git a/WOKA/Authentication/ViewModel/LoginVM.swift b/WOKA/Authentication/ViewModel/LoginVM.swift index 60926f0..18ebb5f 100644 --- a/WOKA/Authentication/ViewModel/LoginVM.swift +++ b/WOKA/Authentication/ViewModel/LoginVM.swift @@ -5,4 +5,36 @@ // Created by Bilal on 03/05/2024. // -import Foundation +import UIKit + +class LoginVM{ + + weak var vc : LoginVC! + + func initView(){ + vc.passwordTF.delegate = self.vc + vc.userNameTF.delegate = self.vc + + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + let color3 = #colorLiteral(red: 0.968627451, green: 0.7882352941, blue: 0.1294117647, alpha: 1) + let color4 = #colorLiteral(red: 0.968627451, green: 0.4196078431, blue: 0.1098039216, alpha: 1) + vc.createAccountBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + vc.createAccountBtn.roundCorner() + + vc.loginBtn.applyGradient(colors: [color4, color3], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 0.8)) + vc.loginBtn.roundCorner() + + vc.passwordTF.roundCorner() + vc.userNameTF.roundCorner() + vc.passwordTF.enablePasswordToggle() + vc.passwordTF.rightView?.isHidden = true + } + + // Function to handle tap on Password Toggle icon + @objc func passwordIconTapped() { + vc.passwordTF.isSelected.toggle() + vc.passwordTF.isSecureTextEntry.toggle() + } + +} diff --git a/WOKA/Authentication/ViewModel/SelectAvatarVM.swift b/WOKA/Authentication/ViewModel/SelectAvatarVM.swift index cd8f9ec..e644370 100644 --- a/WOKA/Authentication/ViewModel/SelectAvatarVM.swift +++ b/WOKA/Authentication/ViewModel/SelectAvatarVM.swift @@ -12,6 +12,10 @@ class SelectAvatarVM{ weak var vc : SelectAvatarVC! func initView(){ + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + vc.nextBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + vc.nextBtn.roundCorner() setupCell() } diff --git a/WOKA/Constants K/StoryBoard.swift b/WOKA/Constants K/StoryBoard.swift index dce6498..9970348 100644 --- a/WOKA/Constants K/StoryBoard.swift +++ b/WOKA/Constants K/StoryBoard.swift @@ -12,5 +12,6 @@ extension K{ struct StoryBoard{ static let main = "Main" static let authenticationSB = "AuthenticationSB" + static let home = "Home" } } diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index 19f2fe7..a8845e1 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -23,6 +23,13 @@ extension K{ static let userDetailsRegisterVC = "UserDetailsRegisterVC" static let userIntrestVC = "UserIntrestVC" static let selectAvatarVC = "SelectAvatarVC" + static let loginVC = "LoginVC" + static let resetPassUserNameVC = "ResetPassUserNameVC" + static let newPasswordVC = "NewPasswordVC" + } + + struct Home{ + static let homeVC = "HomeVC" } } diff --git a/WOKA/Helpers/UIElements Helper/TextFieldImage.swift b/WOKA/Helpers/UIElements Helper/TextFieldImage.swift index f144f8d..b4fd2e5 100644 --- a/WOKA/Helpers/UIElements Helper/TextFieldImage.swift +++ b/WOKA/Helpers/UIElements Helper/TextFieldImage.swift @@ -36,12 +36,15 @@ extension UITextField { extension UITextField { - func addRightButton(title: String?, tintColor : UIColor, btnImage : UIImage?, target: Any?, action: Selector) { + func addRightButton(title: String?, tintColor : UIColor, btnImage : UIImage?, selectedImage : UIImage? = nil, target: Any?, action: Selector) { // Create a button let button = UIButton(type: .system) button.setTitle(title, for: .normal) button.addTarget(target, action: action, for: .touchUpInside) button.setImage(btnImage, for: .normal) + if let selectedImage{ + button.setImage(selectedImage, for: .selected) + } button.tintColor = tintColor button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) // Set the button as the right view of the text field diff --git a/WOKA/Helpers/UIElements Helper/TextFieldPassword.swift b/WOKA/Helpers/UIElements Helper/TextFieldPassword.swift index 775731e..478c52e 100644 --- a/WOKA/Helpers/UIElements Helper/TextFieldPassword.swift +++ b/WOKA/Helpers/UIElements Helper/TextFieldPassword.swift @@ -5,4 +5,29 @@ // Created by Bilal on 03/05/2024. // -import Foundation +import UIKit + +extension UITextField { + fileprivate func setPasswordToggleImage(_ button: UIButton) { + if(isSecureTextEntry){ + button.setImage(UIImage(named: "EyeOpenIcon"), for: .normal) + }else{ + button.setImage(UIImage(named: "EyeCloseIcon"), for: .normal) + } + } + + func enablePasswordToggle(){ + let button = UIButton(type: .custom) + setPasswordToggleImage(button) + button.tintColor = UIColor.lightGray + button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 15) + button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25)) + button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside) + self.rightView = button + self.rightViewMode = .always + } + @IBAction func togglePasswordView(_ sender: Any) { + self.isSecureTextEntry = !self.isSecureTextEntry + setPasswordToggleImage(sender as! UIButton) + } +} diff --git a/WOKA/Helpers/Validations/ValidatorClass.swift b/WOKA/Helpers/Validations/ValidatorClass.swift index 94eb8b7..09ed550 100644 --- a/WOKA/Helpers/Validations/ValidatorClass.swift +++ b/WOKA/Helpers/Validations/ValidatorClass.swift @@ -5,4 +5,62 @@ // Created by Bilal on 03/05/2024. // -import Foundation +import UIKit + +class ValidatorClass { + static let sharedInstanec = ValidatorClass() + + func validateName(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + let currentText = textField.text ?? "" + + // dont allow leading space for names + if (range.location == 0 && string == " ") { + return false + } + + // Check if the replacement string is valid (contains only letters and spaces) + if !string.nameCharacterOnly(){return false} + + // Ensure that the first and last characters are not spaces + if currentText.isEmpty && string == " " { + return false + } + + // Allow only one space between first name, middle name, and last name + if string == " " { + let components = currentText.components(separatedBy: " ") + + //Block user from adding 2 spaces in trailing word + if components.last == "" && string == " "{ + return false + } + + if (currentText as NSString).replacingCharacters(in: range, with: string).contains(" "){ + return false + } + + let filteredComponents = components.filter { !$0.isEmpty } + if filteredComponents.count >= 6 { + return false + } + } + + // Check the length limit (e.g., adjust to your requirements) + let newLength = currentText.count + string.count - range.length + return newLength <= 50 // Adjust the limit as needed. + } + + func limitCharacter(length : Int, _ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{ + let maxLength = length + let currentString = (textField.text ?? "") as NSString + let newString = currentString.replacingCharacters(in: range, with: string) + return newString.count <= maxLength + } + + func limitCharacterTV(length : Int, _ textView: UITextView, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{ + let maxLength = length + let currentString = (textView.text ?? "") as NSString + let newString = currentString.replacingCharacters(in: range, with: string) + return newString.count <= maxLength + } +} diff --git a/WOKA/Home/Home.storyboard b/WOKA/Home/Home.storyboard index dd79351..e7fbf2e 100644 --- a/WOKA/Home/Home.storyboard +++ b/WOKA/Home/Home.storyboard @@ -1,7 +1,9 @@ - + + - + + @@ -20,6 +22,7 @@ + diff --git a/WOKA/OnBoarding Module/Controller/OnBoardVC.swift b/WOKA/OnBoarding Module/Controller/OnBoardVC.swift index dee309a..f7fe5f6 100644 --- a/WOKA/OnBoarding Module/Controller/OnBoardVC.swift +++ b/WOKA/OnBoarding Module/Controller/OnBoardVC.swift @@ -60,6 +60,9 @@ class OnBoardVC: UIViewController { } @IBAction func loginBtnTapped(_ sender: UIButton) { + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.loginVC) as! LoginVC + self.navigationController?.pushViewController(vc, animated: true) } diff --git a/WOKA/OnBoarding Module/Controller/SplashVC.swift b/WOKA/OnBoarding Module/Controller/SplashVC.swift index 9d11623..8d074be 100644 --- a/WOKA/OnBoarding Module/Controller/SplashVC.swift +++ b/WOKA/OnBoarding Module/Controller/SplashVC.swift @@ -29,36 +29,36 @@ class SplashVC: UIViewController { } @IBAction func languageBtnTapped(_ sender: UIButton) { - let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) - let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.userIntrestVC) as! UserIntrestVC - self.navigationController?.pushViewController(vc, animated: true) -// switch sender{ -// case hindiBtn: -// K.GVar.localized = K.LocalizedEnum.hindi -// case englishBtn: -// K.GVar.localized = K.LocalizedEnum.english -// default: -// K.GVar.localized = K.LocalizedEnum.english -// } -// -// let sb = UIStoryboard(name: K.StoryBoard.main, bundle: nil) -// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.OnBoarding.onBoardVC) as! OnBoardVC -// -// // Create a CATransition instance -// let transition = CATransition() -// transition.duration = 0.3 // Set the duration of the animation -// transition.type = CATransitionType.fade // Set the type of animation to fade -// -// // Optionally, set other properties such as timing function, subtype, etc. -// // transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) -// // transition.subtype = CATransitionSubtype.fromTop -// -// // Get the navigation controller -// guard let navigationController = navigationController else { return } -// -// // Perform the push animation with the custom transition -// navigationController.view.layer.add(transition, forKey: nil) -// navigationController.pushViewController(vc, animated: false) +// let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) +// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.loginVC) as! LoginVC +// self.navigationController?.pushViewController(vc, animated: true) + switch sender{ + case hindiBtn: + K.GVar.localized = K.LocalizedEnum.hindi + case englishBtn: + K.GVar.localized = K.LocalizedEnum.english + default: + K.GVar.localized = K.LocalizedEnum.english + } + + let sb = UIStoryboard(name: K.StoryBoard.main, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.OnBoarding.onBoardVC) as! OnBoardVC + + // Create a CATransition instance + let transition = CATransition() + transition.duration = 0.3 // Set the duration of the animation + transition.type = CATransitionType.fade // Set the type of animation to fade + + // Optionally, set other properties such as timing function, subtype, etc. + // transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + // transition.subtype = CATransitionSubtype.fromTop + + // Get the navigation controller + guard let navigationController = navigationController else { return } + + // Perform the push animation with the custom transition + navigationController.view.layer.add(transition, forKey: nil) + navigationController.pushViewController(vc, animated: false) } func animateImageScale() {