diff --git a/Podfile b/Podfile index 2f2eda5..2073593 100644 --- a/Podfile +++ b/Podfile @@ -6,8 +6,13 @@ target 'WOKA' do use_frameworks! pod 'IQKeyboardManagerSwift', '~> 7.0.2' + + # GIF Animations pod 'lottie-ios' + #Network call + pod 'Alamofire' , '~> 5.9.6' + # Bottom line is for removing IPHONEOS_DEPLOYMENT_TARGET post_install do |installer| installer.generated_projects.each do |project| diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index f749848..0f6eefc 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -19,6 +19,21 @@ 523ED27F2BDA2BC900CFED02 /* WOKAUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523ED27E2BDA2BC900CFED02 /* WOKAUITests.swift */; }; 523ED2812BDA2BC900CFED02 /* WOKAUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523ED2802BDA2BC900CFED02 /* WOKAUITestsLaunchTests.swift */; }; 5257B2652BDFB6F50086D79B /* CheckPhoneHomeBtnOrNotch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5257B2642BDFB6F50086D79B /* CheckPhoneHomeBtnOrNotch.swift */; }; + 525953CF2BE8B28F00191286 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525953CE2BE8B28F00191286 /* Utilities.swift */; }; + 525953D12BE8B2B200191286 /* LLSpinner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525953D02BE8B2B200191286 /* LLSpinner.swift */; }; + 525953D42BE8B2DF00191286 /* UIApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525953D32BE8B2DF00191286 /* UIApplication.swift */; }; + 525954102BE8B72900191286 /* FontCustom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259540F2BE8B72900191286 /* FontCustom.swift */; }; + 525954122BE8C84900191286 /* Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954112BE8C84900191286 /* Toast.swift */; }; + 525954142BE8C87300191286 /* ExtensionVCToastAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954132BE8C87300191286 /* ExtensionVCToastAlert.swift */; }; + 525954172BE8CAD300191286 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954162BE8CAD300191286 /* NetworkManager.swift */; }; + 525954192BE8CC3400191286 /* ConstantString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954182BE8CC3400191286 /* ConstantString.swift */; }; + 5259541B2BE8D6F900191286 /* NetworkReachibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259541A2BE8D6F900191286 /* NetworkReachibility.swift */; }; + 5259541D2BE8D94400191286 /* QueueHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259541C2BE8D94400191286 /* QueueHelper.swift */; }; + 5259541F2BE8E93500191286 /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 5259541E2BE8E93500191286 /* Config.xcconfig */; }; + 525954212BE8EB7900191286 /* APIEndPoints.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954202BE8EB7900191286 /* APIEndPoints.swift */; }; + 525954232BE8F00400191286 /* BaseResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954222BE8F00400191286 /* BaseResponseModel.swift */; }; + 525954252BE8F01600191286 /* ValueWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954242BE8F01600191286 /* ValueWrapper.swift */; }; + 525954272BE9178F00191286 /* UserDataDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954262BE9178F00191286 /* UserDataDM.swift */; }; 52663FF52BDFAB830001D8CE /* TextFieldErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF42BDFAB830001D8CE /* TextFieldErrorView.swift */; }; 52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF62BDFACF60001D8CE /* ShadowView.swift */; }; 52663FF92BDFAF110001D8CE /* EmailVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF82BDFAF110001D8CE /* EmailVM.swift */; }; @@ -121,6 +136,21 @@ 523ED27E2BDA2BC900CFED02 /* WOKAUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WOKAUITests.swift; sourceTree = ""; }; 523ED2802BDA2BC900CFED02 /* WOKAUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WOKAUITestsLaunchTests.swift; sourceTree = ""; }; 5257B2642BDFB6F50086D79B /* CheckPhoneHomeBtnOrNotch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckPhoneHomeBtnOrNotch.swift; sourceTree = ""; }; + 525953CE2BE8B28F00191286 /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; + 525953D02BE8B2B200191286 /* LLSpinner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLSpinner.swift; sourceTree = ""; }; + 525953D32BE8B2DF00191286 /* UIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIApplication.swift; sourceTree = ""; }; + 5259540F2BE8B72900191286 /* FontCustom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontCustom.swift; sourceTree = ""; }; + 525954112BE8C84900191286 /* Toast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = ""; }; + 525954132BE8C87300191286 /* ExtensionVCToastAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionVCToastAlert.swift; sourceTree = ""; }; + 525954162BE8CAD300191286 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; + 525954182BE8CC3400191286 /* ConstantString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantString.swift; sourceTree = ""; }; + 5259541A2BE8D6F900191286 /* NetworkReachibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReachibility.swift; sourceTree = ""; }; + 5259541C2BE8D94400191286 /* QueueHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueHelper.swift; sourceTree = ""; }; + 5259541E2BE8E93500191286 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; + 525954202BE8EB7900191286 /* APIEndPoints.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIEndPoints.swift; sourceTree = ""; }; + 525954222BE8F00400191286 /* BaseResponseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseResponseModel.swift; sourceTree = ""; }; + 525954242BE8F01600191286 /* ValueWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValueWrapper.swift; sourceTree = ""; }; + 525954262BE9178F00191286 /* UserDataDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDataDM.swift; sourceTree = ""; }; 52663FF42BDFAB830001D8CE /* TextFieldErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldErrorView.swift; sourceTree = ""; }; 52663FF62BDFACF60001D8CE /* ShadowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShadowView.swift; sourceTree = ""; }; 52663FF82BDFAF110001D8CE /* EmailVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailVM.swift; sourceTree = ""; }; @@ -272,6 +302,7 @@ 523ED25C2BDA2BC700CFED02 /* WOKA */ = { isa = PBXGroup; children = ( + 525954152BE8CAC900191286 /* Network Adapter */, 9CBCB2A62BE5104F007D7934 /* Home */, 52C6E01F2BE3ADD800E22D59 /* Default Enum */, 9C56E83E2BDBE4FB00E4CA14 /* Authentication */, @@ -283,6 +314,7 @@ 523ED2932BDA3D0100CFED02 /* Assets */, 523ED2682BDA2BC900CFED02 /* LaunchScreen.storyboard */, 523ED26B2BDA2BC900CFED02 /* Info.plist */, + 5259541E2BE8E93500191286 /* Config.xcconfig */, ); path = WOKA; sourceTree = ""; @@ -373,10 +405,43 @@ 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */, 9C56E8302BDBC3EF00E4CA14 /* Exo2-SemiBold.ttf */, 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */, + 5259540F2BE8B72900191286 /* FontCustom.swift */, ); path = Fonts; sourceTree = ""; }; + 525953CD2BE8B28100191286 /* ActivityToast&Indicator */ = { + isa = PBXGroup; + children = ( + 525953CE2BE8B28F00191286 /* Utilities.swift */, + 525953D02BE8B2B200191286 /* LLSpinner.swift */, + 525954112BE8C84900191286 /* Toast.swift */, + 525954132BE8C87300191286 /* ExtensionVCToastAlert.swift */, + ); + path = "ActivityToast&Indicator"; + sourceTree = ""; + }; + 525953D22BE8B2CD00191286 /* UIApplication */ = { + isa = PBXGroup; + children = ( + 525953D32BE8B2DF00191286 /* UIApplication.swift */, + ); + path = UIApplication; + sourceTree = ""; + }; + 525954152BE8CAC900191286 /* Network Adapter */ = { + isa = PBXGroup; + children = ( + 525954162BE8CAD300191286 /* NetworkManager.swift */, + 5259541A2BE8D6F900191286 /* NetworkReachibility.swift */, + 5259541C2BE8D94400191286 /* QueueHelper.swift */, + 525954202BE8EB7900191286 /* APIEndPoints.swift */, + 525954222BE8F00400191286 /* BaseResponseModel.swift */, + 525954242BE8F01600191286 /* ValueWrapper.swift */, + ); + path = "Network Adapter"; + sourceTree = ""; + }; 52C6E01F2BE3ADD800E22D59 /* Default Enum */ = { isa = PBXGroup; children = ( @@ -388,6 +453,8 @@ 52C8B0512BDA4B51003B51D0 /* Helpers */ = { isa = PBXGroup; children = ( + 525953D22BE8B2CD00191286 /* UIApplication */, + 525953CD2BE8B28100191286 /* ActivityToast&Indicator */, 5202AAFF2BDFA7860043B7BD /* Validations */, 52C8B06A2BDA6E7A003B51D0 /* Localized */, 52C8B0522BDA4B58003B51D0 /* UIElements Helper */, @@ -426,6 +493,7 @@ 9C27E1642BDB6FBC00EC1DA9 /* StoryBoardID.swift */, 9C27E16C2BDB852F00EC1DA9 /* GVar.swift */, 9C27E16E2BDB866500EC1DA9 /* CellIdentifier.swift */, + 525954182BE8CC3400191286 /* ConstantString.swift */, ); path = "Constants K"; sourceTree = ""; @@ -480,6 +548,7 @@ 9C56E83F2BDBE50200E4CA14 /* Model */ = { isa = PBXGroup; children = ( + 525954262BE9178F00191286 /* UserDataDM.swift */, ); path = Model; sourceTree = ""; @@ -666,6 +735,7 @@ 52C8B05B2BDA5924003B51D0 /* WokaSplashSound.m4a in Resources */, 523ED2652BDA2BC700CFED02 /* Base in Resources */, 52C6E01C2BE383C000E22D59 /* YourIntrestCell.xib in Resources */, + 5259541F2BE8E93500191286 /* Config.xcconfig in Resources */, 9C56E8392BDBC3F000E4CA14 /* Exo2-Regular.ttf in Resources */, 52C6E0262BE3B46A00E22D59 /* SelectAvatarCell.xib in Resources */, 52C8B0712BDA7512003B51D0 /* PassingCloud.json in Resources */, @@ -738,18 +808,23 @@ files = ( 52D774EF2BDFC50D001D87DE /* StringValidations.swift in Sources */, 5272FCE32BDFDB05000ECB1D /* UserDetailsRegisterVC.swift in Sources */, + 525954102BE8B72900191286 /* FontCustom.swift in Sources */, 5202AAFE2BDF90590043B7BD /* TextFieldImage.swift in Sources */, 52C6E0232BE3B3E300E22D59 /* SelectAvatarVC.swift in Sources */, 52C8B06C2BDA6E87003B51D0 /* LocalizedString.swift in Sources */, + 525953D42BE8B2DF00191286 /* UIApplication.swift in Sources */, 52CC38C32BDF812F00B74C3E /* LocalisedElements.swift in Sources */, 52CA28FC2BE11A0400708B49 /* UserIntrestVM.swift in Sources */, 9C27E1602BDB6ECA00EC1DA9 /* UserDefaultsStruct.swift in Sources */, + 5259541D2BE8D94400191286 /* QueueHelper.swift in Sources */, + 525954232BE8F00400191286 /* BaseResponseModel.swift in Sources */, 9C27E1692BDB76F200EC1DA9 /* OnBoardVM.swift in Sources */, 523ED2622BDA2BC700CFED02 /* SplashVC.swift in Sources */, 9CDC343C2BDBBC6B00093089 /* SelectAgeVC.swift in Sources */, 52C8B0542BDA4BD1003B51D0 /* RoundCorner.swift in Sources */, 52C8B0572BDA57DB003B51D0 /* Constant.swift in Sources */, 5202AB012BDFA7900043B7BD /* EmailValidation.swift in Sources */, + 525954192BE8CC3400191286 /* ConstantString.swift in Sources */, 52D774EB2BDFC0BF001D87DE /* OTPVC.swift in Sources */, 9C27E16F2BDB866500EC1DA9 /* CellIdentifier.swift in Sources */, 9C27E1632BDB6F1900EC1DA9 /* AuthFunc.swift in Sources */, @@ -757,6 +832,7 @@ 52C8B0592BDA57FA003B51D0 /* StaticFilesString.swift in Sources */, 52C8B05D2BDA5AA7003B51D0 /* ApplyGradrient.swift in Sources */, 52C6E01B2BE383C000E22D59 /* YourIntrestCell.swift in Sources */, + 525954142BE8C87300191286 /* ExtensionVCToastAlert.swift in Sources */, 523ED25E2BDA2BC700CFED02 /* AppDelegate.swift in Sources */, 52D774ED2BDFC13F001D87DE /* OTPVM.swift in Sources */, 9CBCB2A32BE50C95007D7934 /* ResetPassUserNameVC.swift in Sources */, @@ -766,17 +842,24 @@ 9C56E83B2BDBC6E600E4CA14 /* SelectAgeVM.swift in Sources */, 52CA28FA2BE119F500708B49 /* UserIntrestVC.swift in Sources */, 9C27E16B2BDB774D00EC1DA9 /* CarouselData.swift in Sources */, + 525954212BE8EB7900191286 /* APIEndPoints.swift in Sources */, 523ED2602BDA2BC700CFED02 /* SceneDelegate.swift in Sources */, 9CBCB2AA2BE51A52007D7934 /* HomeVC.swift in Sources */, 52D774E92BDFBDA4001D87DE /* AuthenticationStringConstant.swift in Sources */, + 5259541B2BE8D6F900191286 /* NetworkReachibility.swift in Sources */, 9C27E1672BDB706700EC1DA9 /* StoryBoard.swift in Sources */, 52C8B0692BDA6E1E003B51D0 /* LocalizedEnum.swift in Sources */, + 525954122BE8C84900191286 /* Toast.swift in Sources */, + 525954172BE8CAD300191286 /* NetworkManager.swift in Sources */, + 525954252BE8F01600191286 /* ValueWrapper.swift in Sources */, 52C6E01E2BE3847F00E22D59 /* BorderView.swift in Sources */, 52C8B0742BDA7626003B51D0 /* OnBoardVC.swift in Sources */, + 525953CF2BE8B28F00191286 /* Utilities.swift in Sources */, 9CBCB2A12BE4E50A007D7934 /* TextFieldPassword.swift in Sources */, 9C56E8482BDBEFAB00E4CA14 /* AssetColor.swift in Sources */, 9CBCB29D2BE4D6BB007D7934 /* LoginVM.swift in Sources */, 5272FCE52BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift in Sources */, + 525954272BE9178F00191286 /* UserDataDM.swift in Sources */, 9C27E1652BDB6FBC00EC1DA9 /* StoryBoardID.swift in Sources */, 9C27E1722BDB86B600EC1DA9 /* OnBoardCell.swift in Sources */, 52C8B05F2BDA5AFA003B51D0 /* SplashVM.swift in Sources */, @@ -790,6 +873,7 @@ 9C56E8462BDBEE6400E4CA14 /* EmailVC.swift in Sources */, 52663FFB2BDFB1700001D8CE /* TextFieldShadow.swift in Sources */, 52C6E0212BE3ADE300E22D59 /* GenderEnum.swift in Sources */, + 525953D12BE8B2B200191286 /* LLSpinner.swift in Sources */, 52C6E0272BE3B46A00E22D59 /* SelectAvatarCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -869,6 +953,7 @@ /* Begin XCBuildConfiguration section */ 523ED2822BDA2BC900CFED02 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5259541E2BE8E93500191286 /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -933,6 +1018,7 @@ }; 523ED2832BDA2BC900CFED02 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5259541E2BE8E93500191286 /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; diff --git a/WOKA/Assets/Fonts/FontCustom.swift b/WOKA/Assets/Fonts/FontCustom.swift index ab312dd..23ee830 100644 --- a/WOKA/Assets/Fonts/FontCustom.swift +++ b/WOKA/Assets/Fonts/FontCustom.swift @@ -1,8 +1,26 @@ // -// FontCusto.swift +// FontCustom.swift // WOKA // // Created by MacBook Pro on 06/05/24. // -import Foundation +import UIKit + +enum FontsCustomEnum : String{ + case Exo2_Bold = "Exo2-Bold" + case Exo2_ExtraBold = "Exo2-ExtraBold" + case Exo2_Medium = "Exo2-Medium" + case Exo2_Regular = "Exo2-Regular" + case Exo2_SemiBold = "Exo2-SemiBold" + case Exo2_Thin = "Exo2-Thin" +} + +final class FontCustom{ + + static let shareInstance = FontCustom() + + func customFont(fontName : FontsCustomEnum , size : CGFloat = 16.0)-> UIFont{ + UIFont(name: fontName.rawValue, size: size)! + } +} diff --git a/WOKA/Authentication/Controller/EmailVC.swift b/WOKA/Authentication/Controller/EmailVC.swift index 0c44f88..0027fcc 100644 --- a/WOKA/Authentication/Controller/EmailVC.swift +++ b/WOKA/Authentication/Controller/EmailVC.swift @@ -38,6 +38,7 @@ class EmailVC: UIViewController { } @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { + Utilities.startProgressHUD() DispatchQueue.main.async { [weak self] in guard let self else{return} //validate email fiirst @@ -45,22 +46,43 @@ class EmailVC: UIViewController { if emailValidate != .isCorrect{ enterEmailTF.rightView?.isHidden = false enterEmailTF.setError(emailValidate.rawValue, show: true) + Utilities.dismissProgressHUD() return } - - let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) - let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.oTPVC) as! OTPVC - self.navigationController?.pushViewController(vc, animated: true) + vm.checkEmail() + +// let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) +// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.oTPVC) as! OTPVC +// self.navigationController?.pushViewController(vc, animated: true) } } } +// MARK: - TextField Delegate + extension EmailVC : UITextFieldDelegate{ func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{ - - return true + switch textField{ + case enterEmailTF: + if let rightView = textField.rightView { + // Hide the right view + rightView.isHidden = true + + // Check if the right view is hidden + if rightView.isHidden { + // If hidden, hide the associated error view + if let errorView = errorViews.object(forKey: enterEmailTF) { + errorView.isHidden = true + } + } + } + + return ValidatorClass.sharedInstanec.limitCharacter(length: 255,textField, shouldChangeCharactersIn: range, replacementString: string) + default: + return true + } } } diff --git a/WOKA/Authentication/Controller/LoginVC.swift b/WOKA/Authentication/Controller/LoginVC.swift index a411cf5..b0eb48c 100644 --- a/WOKA/Authentication/Controller/LoginVC.swift +++ b/WOKA/Authentication/Controller/LoginVC.swift @@ -25,6 +25,7 @@ class LoginVC: UIViewController { } @IBAction func loginBtnTapped(_ sender: LocalisedElementsButton) { + vm.loginUser() } @IBAction func createAccountBtnTapped(_ sender: LocalisedElementsButton) { diff --git a/WOKA/Authentication/Model/UserDataDM.swift b/WOKA/Authentication/Model/UserDataDM.swift index d244a6f..0eace71 100644 --- a/WOKA/Authentication/Model/UserDataDM.swift +++ b/WOKA/Authentication/Model/UserDataDM.swift @@ -6,3 +6,62 @@ // import Foundation + +// MARK: - UserDataDM +struct UserDataDM: Codable { + let result: Result? + + // MARK: - Result + struct Result: Codable { + let id: Int? + let username, fullname: String? + let gender: Gender? + let birthdate, email: String? + let avtar: String? + let userType: String? + let languageMasterID: Int? + let isActive: String? + let deletedAt: String? + let lastLogin, rememberToken: String? + let childDetail: String? + let language: Language? + let alreadyLoggedIn: Bool? + + enum CodingKeys: String, CodingKey { + case id, username, fullname, gender, birthdate, email, avtar + case userType = "user_type" + case languageMasterID = "language_master_id" + case isActive = "is_active" + case deletedAt = "deleted_at" + case lastLogin = "last_login" + case rememberToken = "remember_token" + case childDetail = "child_detail" + case language + case alreadyLoggedIn = "already_logged_in" + } + } + + // MARK: - Gender + struct Gender: Codable { + let id: Int? + let genderName: String? + + enum CodingKeys: String, CodingKey { + case id + case genderName = "gender_name" + } + } + + // MARK: - Language + struct Language: Codable { + let id: Int? + let languageName: String? + + enum CodingKeys: String, CodingKey { + case id + case languageName = "language_name" + } + } +} + + diff --git a/WOKA/Authentication/ViewModel/EmailVM.swift b/WOKA/Authentication/ViewModel/EmailVM.swift index 60eaac3..d8035b3 100644 --- a/WOKA/Authentication/ViewModel/EmailVM.swift +++ b/WOKA/Authentication/ViewModel/EmailVM.swift @@ -6,6 +6,7 @@ // import UIKit +import Alamofire class EmailVM{ @@ -36,7 +37,7 @@ class EmailVM{ vc.enterEmailTF.placeholder = K.AuthenticationStringConstant.enterParentsEmail.localized(loc: K.GVar.localized) vc.beSafeLabel.text = K.AuthenticationStringConstant.safeBelow.localized(loc: K.GVar.localized) vc.emailLabel.text = K.AuthenticationStringConstant.emailBelow.localized(loc: K.GVar.localized) - } + } } // Function to handle tap on validation icon @@ -46,4 +47,59 @@ class EmailVM{ errorView.isHidden.toggle() } } + + func checkEmail(){ + let params: Parameters = [ + "email": vc.enterEmailTF.text!, + "user_type": "2" + ] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.check_exist_email, method: .post ,parameters: params) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): +// print(data.message) + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + default: + break + } +// switch data.errorCode{ +// case 0: // this means no error +// Utilities.dismissProgressHUD() +// if let data = data.result { +// let sb = UIStoryboard(name: K.StoryBoard.geoFencing, bundle: nil) +// let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.GeoFencing.geoFencingMapVC) as! GeoFencingMapVC +// vcPush.vm.patientLocationLink = data +// self.navigationController?.setNavigationBarHidden(false, animated: true) +// self.navigationController?.pushViewController(vcPush, animated: true) +// }else{ +// let sb = UIStoryboard(name: K.StoryBoard.geoFencing, bundle: nil) +// let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.GeoFencing.geoFencingMapVC) as! GeoFencingMapVC +// self.navigationController?.setNavigationBarHidden(false, animated: true) +// self.navigationController?.pushViewController(vcPush, animated: true) +// } +// case 1: // handle error +// Utilities.dismissProgressHUD() +// self.toast(msg: data.message ?? "Unrecognised error" , time: 2) +// default: +// Utilities.dismissProgressHUD() +// break +// } + case .failure(let error): + Utilities.dismissProgressHUD() + print(error) +// Utilities.dismissProgressHUD() +// switch error { +// case .noNetwork(let message) , .custom(let message), .unknown(let message): +// Utilities.alertWithBtn(title: "", msgBody: message, okBtnStr: "OK", vc: self) +// default: +// self.toast(msg: String(describing: error) , time: 2) +// } + } + } + } } diff --git a/WOKA/Authentication/ViewModel/LoginVM.swift b/WOKA/Authentication/ViewModel/LoginVM.swift index 18ebb5f..55f3461 100644 --- a/WOKA/Authentication/ViewModel/LoginVM.swift +++ b/WOKA/Authentication/ViewModel/LoginVM.swift @@ -6,6 +6,7 @@ // import UIKit +import Alamofire class LoginVM{ @@ -37,4 +38,60 @@ class LoginVM{ vc.passwordTF.isSecureTextEntry.toggle() } + func loginUser(){ + let params: Parameters = [ + "username": vc.userNameTF.text!, + "password": vc.passwordTF.text! + ] + let header : HTTPHeaders = ["device-id" : "12345"] + + Utilities.startProgressHUD() + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + default: + break + } +// switch data.errorCode{ +// case 0: // this means no error +// Utilities.dismissProgressHUD() +// if let data = data.result { +// let sb = UIStoryboard(name: K.StoryBoard.geoFencing, bundle: nil) +// let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.GeoFencing.geoFencingMapVC) as! GeoFencingMapVC +// vcPush.vm.patientLocationLink = data +// self.navigationController?.setNavigationBarHidden(false, animated: true) +// self.navigationController?.pushViewController(vcPush, animated: true) +// }else{ +// let sb = UIStoryboard(name: K.StoryBoard.geoFencing, bundle: nil) +// let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.GeoFencing.geoFencingMapVC) as! GeoFencingMapVC +// self.navigationController?.setNavigationBarHidden(false, animated: true) +// self.navigationController?.pushViewController(vcPush, animated: true) +// } +// case 1: // handle error +// Utilities.dismissProgressHUD() +// self.toast(msg: data.message ?? "Unrecognised error" , time: 2) +// default: +// Utilities.dismissProgressHUD() +// break +// } + case .failure(let error): + Utilities.dismissProgressHUD() + print(error) +// Utilities.dismissProgressHUD() +// switch error { +// case .noNetwork(let message) , .custom(let message), .unknown(let message): +// Utilities.alertWithBtn(title: "", msgBody: message, okBtnStr: "OK", vc: self) +// default: +// self.toast(msg: String(describing: error) , time: 2) +// } + } + } + } } diff --git a/WOKA/Config.xcconfig b/WOKA/Config.xcconfig index 3bb5153..a4ff106 100644 --- a/WOKA/Config.xcconfig +++ b/WOKA/Config.xcconfig @@ -7,3 +7,7 @@ // Configuration settings file format documentation can be found at: // https://help.apple.com/xcode/#/dev745c5c974 + +API_KEY_ID = "admin" +API_KEY_PASS = "Woka@1234" + diff --git a/WOKA/Constants K/ConstantString.swift b/WOKA/Constants K/ConstantString.swift index acdc0d0..0111d50 100644 --- a/WOKA/Constants K/ConstantString.swift +++ b/WOKA/Constants K/ConstantString.swift @@ -1,5 +1,5 @@ // -// File.swift +// ConstantString.swift // WOKA // // Created by MacBook Pro on 06/05/24. @@ -14,7 +14,7 @@ extension K{ static let passRequirement = "- Be at least 8 characters in length. \n- Contain both upper and lowercase alphabetic characters (e.g. A-Z, a-z). \n- Have at least one numerical character (e.g. 0-9). \n- Have at least one special character (e.g. ~!@#$%^&*()_-+=)." - static let unRecognised = "Unreccognised error" + static let unRecognised = "Unrecognised error" static let noInternet = "Make sure you are connected to the internet!" diff --git a/WOKA/Helpers/ActivityToast&Indicator/ExtensionVCToastAlert.swift b/WOKA/Helpers/ActivityToast&Indicator/ExtensionVCToastAlert.swift index 0ccb993..cc9f170 100644 --- a/WOKA/Helpers/ActivityToast&Indicator/ExtensionVCToastAlert.swift +++ b/WOKA/Helpers/ActivityToast&Indicator/ExtensionVCToastAlert.swift @@ -5,4 +5,17 @@ // Created by MacBook Pro on 06/05/24. // -import Foundation +import UIKit + +extension UIViewController{ + + func toast(msg : String , time : CGFloat, completionBlock: (() -> ())? = nil){ + self.view.endEditing(true) + self.view.isUserInteractionEnabled = false + self.view.makeToast(msg, duration: time, point: CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height - 60), title: nil, image: nil, completion: {didTap in + self.view.isUserInteractionEnabled = true + completionBlock?() + }) + + } +} diff --git a/WOKA/Helpers/ActivityToast&Indicator/LLSpinner.swift b/WOKA/Helpers/ActivityToast&Indicator/LLSpinner.swift index 2315c3a..0a53759 100644 --- a/WOKA/Helpers/ActivityToast&Indicator/LLSpinner.swift +++ b/WOKA/Helpers/ActivityToast&Indicator/LLSpinner.swift @@ -1,5 +1,5 @@ // -// File.swift +// LLSpinner.swift // WOKA // // Created by MacBook Pro on 06/05/24. @@ -8,30 +8,68 @@ import UIKit open class LLSpinner { + + // Spinner view internal static var spinnerView: UIActivityIndicatorView? + // Background view behind spinner + internal static var backgroundView: UIView? + // Background view covering entire frame + internal static var frameTintView: UIView? + // Label to display text + internal static var label: UILabel? + // Default spinner style and background color public static var style: UIActivityIndicatorView.Style = .large - public static var backgroundColor: UIColor = UIColor(white: 0, alpha: 0.6) - + public static var backgroundColor: UIColor = UIColor.black.withAlphaComponent(0.3) + // Touch handler closure internal static var touchHandler: (() -> Void)? - public static func spin(style: UIActivityIndicatorView.Style = style, backgroundColor: UIColor = backgroundColor, touchHandler: (() -> Void)? = nil) { + // Function to show spinner + public static func spin(style: UIActivityIndicatorView.Style = style, + backgroundColor: UIColor = backgroundColor, + text: String? = nil, + touchHandler: (() -> Void)? = nil) { if spinnerView == nil, let window = UIApplication.shared.mainKeyWindow { let frame = UIScreen.main.bounds - spinnerView = UIActivityIndicatorView(frame: frame) - spinnerView?.center = CGPoint(x: window.frame.size.width / 2, - y: window.frame.size.height / 2) - spinnerView!.backgroundColor = backgroundColor - spinnerView!.style = style - spinnerView!.color = .white + // Add background view covering entire frame + frameTintView = UIView(frame: frame) + frameTintView?.center = CGPoint(x: window.frame.size.width / 2, + y: window.frame.size.height / 2) + frameTintView?.backgroundColor = backgroundColor + frameTintView?.layer.cornerRadius = 10 + window.addSubview(frameTintView!) + + // Add background view behind spinner + backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 180, height: 120)) + backgroundView?.center = CGPoint(x: window.frame.size.width / 2, + y: window.frame.size.height / 2 - 20) // Adjust vertical position + backgroundView?.backgroundColor = .white + backgroundView?.layer.cornerRadius = 10 + window.addSubview(backgroundView!) + + // Create and add spinner view + spinnerView = UIActivityIndicatorView(style: style) + spinnerView!.center = CGPoint(x: backgroundView!.center.x, + y: backgroundView!.center.y - 10) // Move spinner up + spinnerView!.color = UIColor.appColor(.TextDarkBlue) window.addSubview(spinnerView!) spinnerView!.startAnimating() + // Add label if text is provided + if let text = text { + label = UILabel(frame: CGRect(x: 0, y: spinnerView!.frame.maxY + 10, width: window.frame.size.width, height: 20)) + label?.font = FontCustom().customFont(fontName: .Exo2_Bold, size: 16) + label?.textColor = UIColor.appColor(.TextDarkBlue) + label?.text = text + label?.textAlignment = .center + window.addSubview(label!) + } } + // Attach touch handler if provided if touchHandler != nil { self.touchHandler = touchHandler let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(runTouchHandler)) @@ -39,17 +77,38 @@ open class LLSpinner { } } + // Run touch handler @objc internal static func runTouchHandler() { if touchHandler != nil { touchHandler!() } } + // Function to stop spinner public static func stop() { + // Remove spinner view if let _ = spinnerView { spinnerView!.stopAnimating() spinnerView!.removeFromSuperview() spinnerView = nil } + + // Remove background view behind spinner + if let _ = backgroundView { + backgroundView!.removeFromSuperview() + backgroundView = nil + } + + // Remove label + if let _ = label { + label!.removeFromSuperview() + label = nil + } + + // Remove background view covering entire frame + if let _ = frameTintView { + frameTintView!.removeFromSuperview() + frameTintView = nil + } } } diff --git a/WOKA/Helpers/ActivityToast&Indicator/Toast.swift b/WOKA/Helpers/ActivityToast&Indicator/Toast.swift index a6f38bc..31d0b36 100644 --- a/WOKA/Helpers/ActivityToast&Indicator/Toast.swift +++ b/WOKA/Helpers/ActivityToast&Indicator/Toast.swift @@ -5,4 +5,760 @@ // Created by MacBook Pro on 06/05/24. // -import Foundation +import UIKit +import ObjectiveC + +/** + Toast is a Swift extension that adds toast notifications to the `UIView` object class. + It is intended to be simple, lightweight, and easy to use. Most toast notifications + can be triggered with a single line of code. + + The `makeToast` methods create a new view and then display it as toast. + + The `showToast` methods display any view as toast. + + */ +public extension UIView { + + /** + Keys used for associated objects. + */ + private struct ToastKeys { + static var timer = "com.toast-swift.timer" + static var duration = "com.toast-swift.duration" + static var point = "com.toast-swift.point" + static var completion = "com.toast-swift.completion" + static var activeToasts = "com.toast-swift.activeToasts" + static var activityView = "com.toast-swift.activityView" + static var queue = "com.toast-swift.queue" + } + + /** + Swift closures can't be directly associated with objects via the + Objective-C runtime, so the (ugly) solution is to wrap them in a + class that can be used with associated objects. + */ + private class ToastCompletionWrapper { + let completion: ((Bool) -> Void)? + + init(_ completion: ((Bool) -> Void)?) { + self.completion = completion + } + } + + private enum ToastError: Error { + case missingParameters + } + + private var activeToasts: NSMutableArray { + get { + if let activeToasts = objc_getAssociatedObject(self, &ToastKeys.activeToasts) as? NSMutableArray { + return activeToasts + } else { + let activeToasts = NSMutableArray() + objc_setAssociatedObject(self, &ToastKeys.activeToasts, activeToasts, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + return activeToasts + } + } + } + + private var queue: NSMutableArray { + get { + if let queue = objc_getAssociatedObject(self, &ToastKeys.queue) as? NSMutableArray { + return queue + } else { + let queue = NSMutableArray() + objc_setAssociatedObject(self, &ToastKeys.queue, queue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + return queue + } + } + } + + // MARK: - Make Toast Methods + + /** + Creates and presents a new toast view. + + @param message The message to be displayed + @param duration The toast duration + @param position The toast's position + @param title The title + @param image The image + @param style The style. The shared style will be used when nil + @param completion The completion closure, executed after the toast view disappears. + didTap will be `true` if the toast view was dismissed from a tap. + */ + func makeToast(_ message: String?, duration: TimeInterval = ToastManager.shared.duration, position: ToastPosition = ToastManager.shared.position, title: String? = nil, image: UIImage? = nil, style: ToastStyle = ToastManager.shared.style, completion: ((_ didTap: Bool) -> Void)? = nil) { + do { + let toast = try toastViewForMessage(message, title: title, image: image, style: style) + showToast(toast, duration: duration, position: position, completion: completion) + } catch ToastError.missingParameters { + print("Error: message, title, and image are all nil") + } catch {} + } + + /** + Creates a new toast view and presents it at a given center point. + + @param message The message to be displayed + @param duration The toast duration + @param point The toast's center point + @param title The title + @param image The image + @param style The style. The shared style will be used when nil + @param completion The completion closure, executed after the toast view disappears. + didTap will be `true` if the toast view was dismissed from a tap. + */ + func makeToast(_ message: String?, duration: TimeInterval = ToastManager.shared.duration, point: CGPoint, title: String?, image: UIImage?, style: ToastStyle = ToastManager.shared.style, completion: ((_ didTap: Bool) -> Void)?) { + do { + let toast = try toastViewForMessage(message, title: title, image: image, style: style) + showToast(toast, duration: duration, point: point, completion: completion) + } catch ToastError.missingParameters { + print("Error: message, title, and image cannot all be nil") + } catch {} + } + + // MARK: - Show Toast Methods + + /** + Displays any view as toast at a provided position and duration. The completion closure + executes when the toast view completes. `didTap` will be `true` if the toast view was + dismissed from a tap. + + @param toast The view to be displayed as toast + @param duration The notification duration + @param position The toast's position + @param completion The completion block, executed after the toast view disappears. + didTap will be `true` if the toast view was dismissed from a tap. + */ + func showToast(_ toast: UIView, duration: TimeInterval = ToastManager.shared.duration, position: ToastPosition = ToastManager.shared.position, completion: ((_ didTap: Bool) -> Void)? = nil) { + let point = position.centerPoint(forToast: toast, inSuperview: self) + showToast(toast, duration: duration, point: point, completion: completion) + } + + /** + Displays any view as toast at a provided center point and duration. The completion closure + executes when the toast view completes. `didTap` will be `true` if the toast view was + dismissed from a tap. + + @param toast The view to be displayed as toast + @param duration The notification duration + @param point The toast's center point + @param completion The completion block, executed after the toast view disappears. + didTap will be `true` if the toast view was dismissed from a tap. + */ + func showToast(_ toast: UIView, duration: TimeInterval = ToastManager.shared.duration, point: CGPoint, completion: ((_ didTap: Bool) -> Void)? = nil) { + objc_setAssociatedObject(toast, &ToastKeys.completion, ToastCompletionWrapper(completion), .OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + if ToastManager.shared.isQueueEnabled, activeToasts.count > 0 { + objc_setAssociatedObject(toast, &ToastKeys.duration, NSNumber(value: duration), .OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(toast, &ToastKeys.point, NSValue(cgPoint: point), .OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + queue.add(toast) + } else { + showToast(toast, duration: duration, point: point) + } + } + + // MARK: - Hide Toast Methods + + /** + Hides the active toast. If there are multiple toasts active in a view, this method + hides the oldest toast (the first of the toasts to have been presented). + + @see `hideAllToasts()` to remove all active toasts from a view. + + @warning This method has no effect on activity toasts. Use `hideToastActivity` to + hide activity toasts. + + */ + func hideToast() { + guard let activeToast = activeToasts.firstObject as? UIView else { return } + hideToast(activeToast) + } + + /** + Hides an active toast. + + @param toast The active toast view to dismiss. Any toast that is currently being displayed + on the screen is considered active. + + @warning this does not clear a toast view that is currently waiting in the queue. + */ + func hideToast(_ toast: UIView) { + guard activeToasts.contains(toast) else { return } + hideToast(toast, fromTap: false) + } + + /** + Hides all toast views. + + @param includeActivity If `true`, toast activity will also be hidden. Default is `false`. + @param clearQueue If `true`, removes all toast views from the queue. Default is `true`. + */ + func hideAllToasts(includeActivity: Bool = false, clearQueue: Bool = true) { + if clearQueue { + clearToastQueue() + } + + activeToasts.compactMap { $0 as? UIView } + .forEach { hideToast($0) } + + if includeActivity { + hideToastActivity() + } + } + + /** + Removes all toast views from the queue. This has no effect on toast views that are + active. Use `hideAllToasts(clearQueue:)` to hide the active toasts views and clear + the queue. + */ + func clearToastQueue() { + queue.removeAllObjects() + } + + // MARK: - Activity Methods + + /** + Creates and displays a new toast activity indicator view at a specified position. + + @warning Only one toast activity indicator view can be presented per superview. Subsequent + calls to `makeToastActivity(position:)` will be ignored until `hideToastActivity()` is called. + + @warning `makeToastActivity(position:)` works independently of the `showToast` methods. Toast + activity views can be presented and dismissed while toast views are being displayed. + `makeToastActivity(position:)` has no effect on the queueing behavior of the `showToast` methods. + + @param position The toast's position + */ +// func makeToastActivity(_ position: ToastPosition) { +// // sanity +// guard objc_getAssociatedObject(self, &ToastKeys.activityView) as? UIView == nil else { return } +// +// let toast = createToastActivityView() +// let point = position.centerPoint(forToast: toast, inSuperview: self) +// makeToastActivity(toast, point: point) +// } + + /** + Creates and displays a new toast activity indicator view at a specified position. + + @warning Only one toast activity indicator view can be presented per superview. Subsequent + calls to `makeToastActivity(position:)` will be ignored until `hideToastActivity()` is called. + + @warning `makeToastActivity(position:)` works independently of the `showToast` methods. Toast + activity views can be presented and dismissed while toast views are being displayed. + `makeToastActivity(position:)` has no effect on the queueing behavior of the `showToast` methods. + + @param point The toast's center point + */ +// func makeToastActivity(_ point: CGPoint) { +// // sanity +// guard objc_getAssociatedObject(self, &ToastKeys.activityView) as? UIView == nil else { return } +// +// let toast = createToastActivityView() +// makeToastActivity(toast, point: point) +// } + + /** + Dismisses the active toast activity indicator view. + */ + func hideToastActivity() { + if let toast = objc_getAssociatedObject(self, &ToastKeys.activityView) as? UIView { + UIView.animate(withDuration: ToastManager.shared.style.fadeDuration, delay: 0.0, options: [.curveEaseIn, .beginFromCurrentState], animations: { + toast.alpha = 0.0 + }) { _ in + toast.removeFromSuperview() + objc_setAssociatedObject(self, &ToastKeys.activityView, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + } + + // MARK: - Private Activity Methods + + private func makeToastActivity(_ toast: UIView, point: CGPoint) { + toast.alpha = 0.0 + toast.center = point + + objc_setAssociatedObject(self, &ToastKeys.activityView, toast, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + + self.addSubview(toast) + + UIView.animate(withDuration: ToastManager.shared.style.fadeDuration, delay: 0.0, options: .curveEaseOut, animations: { + toast.alpha = 1.0 + }) + } + +// private func createToastActivityView() -> UIView { +// let style = ToastManager.shared.style +// +// let activityView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: style.activitySize.width, height: style.activitySize.height)) +// activityView.backgroundColor = style.activityBackgroundColor +// activityView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin] +// activityView.layer.cornerRadius = style.cornerRadius +// +// if style.displayShadow { +// activityView.layer.shadowColor = style.shadowColor.cgColor +// activityView.layer.shadowOpacity = style.shadowOpacity +// activityView.layer.shadowRadius = style.shadowRadius +// activityView.layer.shadowOffset = style.shadowOffset +// } +// +// let activityIndicatorView = UIActivityIndicatorView(style: .whiteLarge) +// activityIndicatorView.center = CGPoint(x: activityView.bounds.size.width / 2.0, y: activityView.bounds.size.height / 2.0) +// activityView.addSubview(activityIndicatorView) +// activityIndicatorView.color = style.activityIndicatorColor +// activityIndicatorView.startAnimating() +// +// return activityView +// } + + // MARK: - Private Show/Hide Methods + + private func showToast(_ toast: UIView, duration: TimeInterval, point: CGPoint) { + toast.center = point + toast.alpha = 0.0 + + if ToastManager.shared.isTapToDismissEnabled { + let recognizer = UITapGestureRecognizer(target: self, action: #selector(UIView.handleToastTapped(_:))) + toast.addGestureRecognizer(recognizer) + toast.isUserInteractionEnabled = true + toast.isExclusiveTouch = true + } + + activeToasts.add(toast) + self.addSubview(toast) + + UIView.animate(withDuration: ToastManager.shared.style.fadeDuration, delay: 0.0, options: [.curveEaseOut, .allowUserInteraction], animations: { + toast.alpha = 1.0 + }) { _ in + let timer = Timer(timeInterval: duration, target: self, selector: #selector(UIView.toastTimerDidFinish(_:)), userInfo: toast, repeats: false) + RunLoop.main.add(timer, forMode: .common) + objc_setAssociatedObject(toast, &ToastKeys.timer, timer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + private func hideToast(_ toast: UIView, fromTap: Bool) { + if let timer = objc_getAssociatedObject(toast, &ToastKeys.timer) as? Timer { + timer.invalidate() + } + + UIView.animate(withDuration: ToastManager.shared.style.fadeDuration, delay: 0.0, options: [.curveEaseIn, .beginFromCurrentState], animations: { + toast.alpha = 0.0 + }) { _ in + toast.removeFromSuperview() + self.activeToasts.remove(toast) + + if let wrapper = objc_getAssociatedObject(toast, &ToastKeys.completion) as? ToastCompletionWrapper, let completion = wrapper.completion { + completion(fromTap) + } + + if let nextToast = self.queue.firstObject as? UIView, let duration = objc_getAssociatedObject(nextToast, &ToastKeys.duration) as? NSNumber, let point = objc_getAssociatedObject(nextToast, &ToastKeys.point) as? NSValue { + self.queue.removeObject(at: 0) + self.showToast(nextToast, duration: duration.doubleValue, point: point.cgPointValue) + } + } + } + + // MARK: - Events + + @objc + private func handleToastTapped(_ recognizer: UITapGestureRecognizer) { + guard let toast = recognizer.view else { return } + hideToast(toast, fromTap: true) + } + + @objc + private func toastTimerDidFinish(_ timer: Timer) { + guard let toast = timer.userInfo as? UIView else { return } + hideToast(toast) + } + + // MARK: - Toast Construction + + /** + Creates a new toast view with any combination of message, title, and image. + The look and feel is configured via the style. Unlike the `makeToast` methods, + this method does not present the toast view automatically. One of the `showToast` + methods must be used to present the resulting view. + + @warning if message, title, and image are all nil, this method will throw + `ToastError.missingParameters` + + @param message The message to be displayed + @param title The title + @param image The image + @param style The style. The shared style will be used when nil + @throws `ToastError.missingParameters` when message, title, and image are all nil + @return The newly created toast view + */ + func toastViewForMessage(_ message: String?, title: String?, image: UIImage?, style: ToastStyle) throws -> UIView { + // sanity + guard message != nil || title != nil || image != nil else { + throw ToastError.missingParameters + } + + var messageLabel: UILabel? + var titleLabel: UILabel? + var imageView: UIImageView? + + let wrapperView = UIView() + wrapperView.backgroundColor = style.backgroundColor + wrapperView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin] + wrapperView.layer.cornerRadius = style.cornerRadius + + if style.displayShadow { + wrapperView.layer.shadowColor = UIColor.black.cgColor + wrapperView.layer.shadowOpacity = style.shadowOpacity + wrapperView.layer.shadowRadius = style.shadowRadius + wrapperView.layer.shadowOffset = style.shadowOffset + } + + if let image = image { + imageView = UIImageView(image: image) + imageView?.contentMode = .scaleAspectFit + imageView?.frame = CGRect(x: style.horizontalPadding, y: style.verticalPadding, width: style.imageSize.width, height: style.imageSize.height) + } + + var imageRect = CGRect.zero + + if let imageView = imageView { + imageRect.origin.x = style.horizontalPadding + imageRect.origin.y = style.verticalPadding + imageRect.size.width = imageView.bounds.size.width + imageRect.size.height = imageView.bounds.size.height + } + + if let title = title { + titleLabel = UILabel() + titleLabel?.numberOfLines = style.titleNumberOfLines + titleLabel?.font = style.titleFont + titleLabel?.textAlignment = style.titleAlignment + titleLabel?.lineBreakMode = .byTruncatingTail + titleLabel?.textColor = style.titleColor + titleLabel?.backgroundColor = UIColor.clear + titleLabel?.text = title; + + let maxTitleSize = CGSize(width: (self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, height: self.bounds.size.height * style.maxHeightPercentage) + let titleSize = titleLabel?.sizeThatFits(maxTitleSize) + if let titleSize = titleSize { + titleLabel?.frame = CGRect(x: 0.0, y: 0.0, width: titleSize.width, height: titleSize.height) + } + } + + if let message = message { + messageLabel = UILabel() + messageLabel?.text = message + messageLabel?.numberOfLines = style.messageNumberOfLines + messageLabel?.font = style.messageFont + messageLabel?.textAlignment = style.messageAlignment + messageLabel?.lineBreakMode = .byTruncatingTail; + messageLabel?.textColor = style.messageColor + messageLabel?.backgroundColor = UIColor.clear + + let maxMessageSize = CGSize(width: (self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, height: self.bounds.size.height * style.maxHeightPercentage) + let messageSize = messageLabel?.sizeThatFits(maxMessageSize) + if let messageSize = messageSize { + let actualWidth = min(messageSize.width, maxMessageSize.width) + let actualHeight = min(messageSize.height, maxMessageSize.height) + messageLabel?.frame = CGRect(x: 0.0, y: 0.0, width: actualWidth, height: actualHeight) + } + } + + var titleRect = CGRect.zero + + if let titleLabel = titleLabel { + titleRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding + titleRect.origin.y = style.verticalPadding + titleRect.size.width = titleLabel.bounds.size.width + titleRect.size.height = titleLabel.bounds.size.height + } + + var messageRect = CGRect.zero + + if let messageLabel = messageLabel { + messageRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding + messageRect.origin.y = titleRect.origin.y + titleRect.size.height + style.verticalPadding + messageRect.size.width = messageLabel.bounds.size.width + messageRect.size.height = messageLabel.bounds.size.height + } + + let longerWidth = max(titleRect.size.width, messageRect.size.width) + let longerX = max(titleRect.origin.x, messageRect.origin.x) + let wrapperWidth = max((imageRect.size.width + (style.horizontalPadding * 2.0)), (longerX + longerWidth + style.horizontalPadding)) + let wrapperHeight = max((messageRect.origin.y + messageRect.size.height + style.verticalPadding), (imageRect.size.height + (style.verticalPadding * 2.0))) + + wrapperView.frame = CGRect(x: 0.0, y: 0.0, width: wrapperWidth, height: wrapperHeight) + + if let titleLabel = titleLabel { + titleRect.size.width = longerWidth + titleLabel.frame = titleRect + wrapperView.addSubview(titleLabel) + } + + if let messageLabel = messageLabel { + messageRect.size.width = longerWidth + messageLabel.frame = messageRect + wrapperView.addSubview(messageLabel) + } + + if let imageView = imageView { + wrapperView.addSubview(imageView) + } + + return wrapperView + } + +} + +// MARK: - Toast Style + +/** + `ToastStyle` instances define the look and feel for toast views created via the + `makeToast` methods as well for toast views created directly with + `toastViewForMessage(message:title:image:style:)`. + + @warning `ToastStyle` offers relatively simple styling options for the default + toast view. If you require a toast view with more complex UI, it probably makes more + sense to create your own custom UIView subclass and present it with the `showToast` + methods. +*/ +public struct ToastStyle { + + public init() {} + + /** + The background color. Default is `.black` at 80% opacity. + */ + public var backgroundColor: UIColor = UIColor.black.withAlphaComponent(0.8) + + /** + The title color. Default is `UIColor.whiteColor()`. + */ + public var titleColor: UIColor = .white + + /** + The message color. Default is `.white`. + */ + public var messageColor: UIColor = .white + + /** + A percentage value from 0.0 to 1.0, representing the maximum width of the toast + view relative to it's superview. Default is 0.8 (80% of the superview's width). + */ + public var maxWidthPercentage: CGFloat = 0.8 { + didSet { + maxWidthPercentage = max(min(maxWidthPercentage, 1.0), 0.0) + } + } + + /** + A percentage value from 0.0 to 1.0, representing the maximum height of the toast + view relative to it's superview. Default is 0.8 (80% of the superview's height). + */ + public var maxHeightPercentage: CGFloat = 0.8 { + didSet { + maxHeightPercentage = max(min(maxHeightPercentage, 1.0), 0.0) + } + } + + /** + The spacing from the horizontal edge of the toast view to the content. When an image + is present, this is also used as the padding between the image and the text. + Default is 10.0. + + */ + public var horizontalPadding: CGFloat = 10.0 + + /** + The spacing from the vertical edge of the toast view to the content. When a title + is present, this is also used as the padding between the title and the message. + Default is 10.0. On iOS11+, this value is added added to the `safeAreaInset.top` + and `safeAreaInsets.bottom`. + */ + public var verticalPadding: CGFloat = 10.0 + + /** + The corner radius. Default is 10.0. + */ + public var cornerRadius: CGFloat = 10.0; + + /** + The title font. Default is `.boldSystemFont(16.0)`. + */ + public var titleFont: UIFont = .boldSystemFont(ofSize: 16.0) + + /** + The message font. Default is `.systemFont(ofSize: 16.0)`. + */ + public var messageFont: UIFont = .systemFont(ofSize: 16.0) + + /** + The title text alignment. Default is `NSTextAlignment.Left`. + */ + public var titleAlignment: NSTextAlignment = .left + + /** + The message text alignment. Default is `NSTextAlignment.Left`. + */ + public var messageAlignment: NSTextAlignment = .left + + /** + The maximum number of lines for the title. The default is 0 (no limit). + */ + public var titleNumberOfLines = 0 + + /** + The maximum number of lines for the message. The default is 0 (no limit). + */ + public var messageNumberOfLines = 0 + + /** + Enable or disable a shadow on the toast view. Default is `false`. + */ + public var displayShadow = false + + /** + The shadow color. Default is `.black`. + */ + public var shadowColor: UIColor = .black + + /** + A value from 0.0 to 1.0, representing the opacity of the shadow. + Default is 0.8 (80% opacity). + */ + public var shadowOpacity: Float = 0.8 { + didSet { + shadowOpacity = max(min(shadowOpacity, 1.0), 0.0) + } + } + + /** + The shadow radius. Default is 6.0. + */ + public var shadowRadius: CGFloat = 6.0 + + /** + The shadow offset. The default is 4 x 4. + */ + public var shadowOffset = CGSize(width: 4.0, height: 4.0) + + /** + The image size. The default is 80 x 80. + */ + public var imageSize = CGSize(width: 80.0, height: 80.0) + + /** + The size of the toast activity view when `makeToastActivity(position:)` is called. + Default is 100 x 100. + */ + public var activitySize = CGSize(width: 100.0, height: 100.0) + + /** + The fade in/out animation duration. Default is 0.2. + */ + public var fadeDuration: TimeInterval = 0.2 + + /** + Activity indicator color. Default is `.white`. + */ + public var activityIndicatorColor: UIColor = .white + + /** + Activity background color. Default is `.black` at 80% opacity. + */ + public var activityBackgroundColor: UIColor = UIColor.black.withAlphaComponent(0.8) + +} + +// MARK: - Toast Manager + +/** + `ToastManager` provides general configuration options for all toast + notifications. Backed by a singleton instance. +*/ +public class ToastManager { + + /** + The `ToastManager` singleton instance. + + */ + public static let shared = ToastManager() + + /** + The shared style. Used whenever toastViewForMessage(message:title:image:style:) is called + with with a nil style. + + */ + public var style = ToastStyle() + + /** + Enables or disables tap to dismiss on toast views. Default is `true`. + + */ + public var isTapToDismissEnabled = true + + /** + Enables or disables queueing behavior for toast views. When `true`, + toast views will appear one after the other. When `false`, multiple toast + views will appear at the same time (potentially overlapping depending + on their positions). This has no effect on the toast activity view, + which operates independently of normal toast views. Default is `false`. + + */ + public var isQueueEnabled = false + + /** + The default duration. Used for the `makeToast` and + `showToast` methods that don't require an explicit duration. + Default is 3.0. + + */ + public var duration: TimeInterval = 3.0 + + /** + Sets the default position. Used for the `makeToast` and + `showToast` methods that don't require an explicit position. + Default is `ToastPosition.Bottom`. + + */ + public var position: ToastPosition = .bottom + +} + +// MARK: - ToastPosition + +public enum ToastPosition { + case top + case center + case bottom + + fileprivate func centerPoint(forToast toast: UIView, inSuperview superview: UIView) -> CGPoint { + let topPadding: CGFloat = ToastManager.shared.style.verticalPadding + superview.csSafeAreaInsets.top + let bottomPadding: CGFloat = ToastManager.shared.style.verticalPadding + superview.csSafeAreaInsets.bottom + + switch self { + case .top: + return CGPoint(x: superview.bounds.size.width / 2.0, y: (toast.frame.size.height / 2.0) + topPadding) + case .center: + return CGPoint(x: superview.bounds.size.width / 2.0, y: superview.bounds.size.height / 2.0) + case .bottom: + return CGPoint(x: superview.bounds.size.width / 2.0, y: (superview.bounds.size.height - (toast.frame.size.height / 2.0)) - bottomPadding) + } + } +} + +// MARK: - Private UIView Extensions + +private extension UIView { + + var csSafeAreaInsets: UIEdgeInsets { + if #available(iOS 11.0, *) { + return self.safeAreaInsets + } else { + return .zero + } + } + +} diff --git a/WOKA/Helpers/ActivityToast&Indicator/Utilities.swift b/WOKA/Helpers/ActivityToast&Indicator/Utilities.swift index 3d380db..edfb8e2 100644 --- a/WOKA/Helpers/ActivityToast&Indicator/Utilities.swift +++ b/WOKA/Helpers/ActivityToast&Indicator/Utilities.swift @@ -22,7 +22,7 @@ class Utilities{ // } static func startProgressHUD(progress: Float? = nil) { - LLSpinner.spin() + LLSpinner.spin(text: "Please wait...") // if let progress = progress { // SVProgressHUD.showProgress(progress) // } else { @@ -54,7 +54,7 @@ class Utilities{ alert.setValue(messageMutableString, forKey: "attributedMessage") let okAction = UIAlertAction(title: okBtnStr ?? "OK", style: .default, handler: nil) - okAction.setValue(UIColor.appColor(.AppBaseBlueColor), forKey: "titleTextColor") + okAction.setValue(UIColor.appColor(.TextDarkBlue), forKey: "titleTextColor") alert.addAction(okAction) @@ -70,7 +70,7 @@ class Utilities{ let messageAttributes = [NSAttributedString.Key.font: UIFont(name: "Nunito-Regular", size: 18)!, NSAttributedString.Key.foregroundColor: UIColor.black] let messageString = NSAttributedString(string: msgBody, attributes: messageAttributes) - okAction.setValue(UIColor.appColor(.AppBaseBlueColor), forKey: "titleTextColor") + okAction.setValue(UIColor.appColor(.TextDarkBlue), forKey: "titleTextColor") alert.addAction(okAction) alert.setValue(messageString, forKey: "attributedMessage") diff --git a/WOKA/Helpers/UIApplication/UIApplication.swift b/WOKA/Helpers/UIApplication/UIApplication.swift index 8e19289..baba921 100644 --- a/WOKA/Helpers/UIApplication/UIApplication.swift +++ b/WOKA/Helpers/UIApplication/UIApplication.swift @@ -1,5 +1,5 @@ // -// File.swift +// UIApplication.swift // WOKA // // Created by MacBook Pro on 06/05/24. diff --git a/WOKA/Home/Home.storyboard b/WOKA/Home/Home.storyboard index e7fbf2e..df67627 100644 --- a/WOKA/Home/Home.storyboard +++ b/WOKA/Home/Home.storyboard @@ -1,5 +1,5 @@ - + diff --git a/WOKA/Info.plist b/WOKA/Info.plist index 43ccae6..b1fdb3e 100644 --- a/WOKA/Info.plist +++ b/WOKA/Info.plist @@ -2,6 +2,12 @@ + STAGING_URL + $(STAGING_URL) + API_KEY_ID + $(API_KEY_ID) + API_KEY_PASS + $(API_KEY_PASS) UIUserInterfaceStyle Light UIApplicationSceneManifest diff --git a/WOKA/Main/AppDelegate.swift b/WOKA/Main/AppDelegate.swift index e37b442..efe3fab 100644 --- a/WOKA/Main/AppDelegate.swift +++ b/WOKA/Main/AppDelegate.swift @@ -18,9 +18,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { IQKeyboardManager.shared.enable = true IQKeyboardManager.shared.resignOnTouchOutside = true // IQKeyboardManager.shared.enableAutoToolbar = false - // IQKeyboardManager.shared.layoutIfNeededOnUpdate = true + // Set the authentication ID Pass after app starts + AuthFunc.shareInstance.setAuthIDPass() + + // Set the toast defaults + setupToast() + //Lottie Config to handle rendering LottieConfiguration.shared.renderingEngine = .mainThread return true @@ -43,3 +48,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } +extension AppDelegate { + // MARK: - Toast Setup + + private func setupToast(){ + var style = ToastStyle() + style.displayShadow = true + style.messageColor = UIColor.white + style.backgroundColor = UIColor.appColor(.TextDarkBlue)! + style.messageFont = FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16) + style.titleAlignment = .center + style.messageAlignment = .center + style.cornerRadius = 10 + ToastManager.shared.style = style + + // toggle "tap to dismiss" functionality + ToastManager.shared.isTapToDismissEnabled = true + + // toggle queueing behavior + ToastManager.shared.isQueueEnabled = false + } +} diff --git a/WOKA/Main/AuthFunc.swift b/WOKA/Main/AuthFunc.swift index 8ffc048..f251619 100644 --- a/WOKA/Main/AuthFunc.swift +++ b/WOKA/Main/AuthFunc.swift @@ -14,12 +14,27 @@ class AuthFunc{ This is not for external use! This should only be used for login, registration, Auth Process process & userData Extraction. */ + var player: AVQueuePlayer? var playerLooper: AVPlayerLooper? var userType = UserType.adult + var authID = String() + var authPass = String() + static let shareInstance = AuthFunc() + + func setAuthIDPass(){ + if let id = Bundle.main.infoDictionary?["API_KEY_ID"] as? String{ + authID = id + } + + if let pass = Bundle.main.infoDictionary?["API_KEY_PASS"] as? String{ + authPass = pass + } + } + func playStartUpsound(){ guard let path = Bundle.main.path(forResource: K.StaticFilesString.onBoardMainSound, ofType:"m4a") else { return } diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index e77f3f3..f6d3b51 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -6,3 +6,44 @@ // import Foundation + +// enum to check envirnments +enum EnvironmentCheck{ + case staging + case production +} + +struct APIEndPoints { + + struct BaseURL { + static let staging = "https://wokaland.com/admin/api/" + static let production = "https://simplitend.com" + } + + struct Auth { + static let check_exist_email = makeURL(path: "check_exist_email") + static let login = makeURL(path: "login") + static let login_proceed = makeURL(path: "login_proceed") + } + + // Other endpoint categories... + struct Links { + static let privacyPolicy = "https://www.simplitend.com/privacy-policy" + static let termsAndCondition = "https://www.simplitend.com/terms-and-conditions" + // Other links... + } + + // Helper method to construct full URL from base URL and path + private static func makeURL(path: String) -> URL { + guard let baseURL = baseURLForCurrentEnvironment() else { + fatalError("Base URL not configured for current environment") + } + return baseURL.appendingPathComponent(path) + } + + // Helper method to get base URL based on current environment + private static func baseURLForCurrentEnvironment() -> URL? { + // Determine environment (e.g., staging, production) and return appropriate base URL + return URL(string: BaseURL.staging) + } +} diff --git a/WOKA/Network Adapter/BaseResponseModel.swift b/WOKA/Network Adapter/BaseResponseModel.swift index fc967c0..5162aaf 100644 --- a/WOKA/Network Adapter/BaseResponseModel.swift +++ b/WOKA/Network Adapter/BaseResponseModel.swift @@ -6,3 +6,18 @@ // import Foundation + +// MARK: - BaseResponseModel + +class BaseResponseModel : Codable { +//class BaseResponseModel: Codable { + let success: Int? + let message: String? + let result: T? + + enum CodingKeys: String, CodingKey { + case success + case message + case result + } +} diff --git a/WOKA/Network Adapter/NetworkManager.swift b/WOKA/Network Adapter/NetworkManager.swift index acd13dc..e6dac48 100644 --- a/WOKA/Network Adapter/NetworkManager.swift +++ b/WOKA/Network Adapter/NetworkManager.swift @@ -50,6 +50,7 @@ class NetworkManager{ // Execute the request on the specified queue queue.async { AF.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers, requestModifier: { $0.timeoutInterval = 30 }) + .authenticate(username: "admin", password: "Woka@1234") .validate(statusCode: 200..<300) .responseDecodable(of: T.self) { response in switch response.result { @@ -105,69 +106,4 @@ class NetworkManager{ } } } - } - -// func handleAFError(error: Error)-> Int? { -// if let afError = error as? AFError { -// // This error is of type AFError, and you can access its properties. -// let errorCode = afError.responseCode -// return errorCode -// } else { -// // Handle other types of errors or unsupported cases -// return nil -// } -// } -// -// func uploadFormData( -// url: URLConvertible, -// method: HTTPMethod, -// headers: HTTPHeaders? = nil, -// params : [String : Any]?, -// image : UIImage?, -// formData: [MultipartFormData], -// completionHandler: @escaping (Result) -> Void -// ) { -// -// let imageData = image?.jpegData(compressionQuality: 0.4)! -// let imageKey = "contact_photo" // Change me -// AF.upload(multipartFormData: { multiPart in -// for (key, value) in (params ?? [:]) { -// if let arrayObj = value as? [Any] { -// for index in 0..) in -// switch response.result { -// case .success(let value): -// completionHandler(.success(value)) -// case .failure(let error): -// if let statusCode = response.response?.statusCode { -// switch statusCode { -// case 400..<500: -// // Handle client-side errors (4xx) -// completionHandler(.failure(.custom(message: "Client-side error: \(statusCode)"))) -// case 500..<600: -// // Handle server-side errors (5xx) -// completionHandler(.failure(.custom(message: "Server-side error: \(statusCode)"))) -// default: -// completionHandler(.failure(.unknown)) -// } -// } else { -// completionHandler(.failure(.unknown)) -// } -// } -// } -// } -//} diff --git a/WOKA/Network Adapter/QueueHelper.swift b/WOKA/Network Adapter/QueueHelper.swift index 869a83a..e0b7690 100644 --- a/WOKA/Network Adapter/QueueHelper.swift +++ b/WOKA/Network Adapter/QueueHelper.swift @@ -1,5 +1,5 @@ // -// File.swift +// QueueHelper.swift // WOKA // // Created by MacBook Pro on 06/05/24. @@ -13,8 +13,8 @@ import Foundation */ class QueueHelper { - static let queue = DispatchQueue(label: "com.simpliTend") - static let queueHome = DispatchQueue(label: "com.simpliTend.home") + static let queue = DispatchQueue(label: "com.woka") + static let queueHome = DispatchQueue(label: "com.woka.home") static let group = DispatchGroup() static let group2 = DispatchGroup() static let group3 = DispatchGroup() diff --git a/WOKA/Network Adapter/ValueWrapper.swift b/WOKA/Network Adapter/ValueWrapper.swift index 462b414..2cd085f 100644 --- a/WOKA/Network Adapter/ValueWrapper.swift +++ b/WOKA/Network Adapter/ValueWrapper.swift @@ -1,5 +1,5 @@ // -// File.swift +// ValueWrapper.swift // WOKA // // Created by MacBook Pro on 06/05/24. diff --git a/WOKA/OnBoarding Module/Controller/SplashVC.swift b/WOKA/OnBoarding Module/Controller/SplashVC.swift index 8d074be..7035efe 100644 --- a/WOKA/OnBoarding Module/Controller/SplashVC.swift +++ b/WOKA/OnBoarding Module/Controller/SplashVC.swift @@ -29,9 +29,6 @@ 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.loginVC) as! LoginVC -// self.navigationController?.pushViewController(vc, animated: true) switch sender{ case hindiBtn: K.GVar.localized = K.LocalizedEnum.hindi