LoginVC.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. //
  2. // LoginVC.swift
  3. // Sirani
  4. //
  5. // Created by Anhar Solehudin on 24/03/19.
  6. // Copyright © 2019 Anhar Solehudin. All rights reserved.
  7. //
  8. import UIKit
  9. class LoginVC: UIViewController {
  10. // Outlets
  11. @IBOutlet weak var loginLayout: UIScrollView!
  12. @IBOutlet weak var profileLayout: UIScrollView!
  13. @IBOutlet weak var inputUsername: RoundTextField!
  14. @IBOutlet weak var inputPassword: RoundTextField!
  15. @IBOutlet weak var txtUsernameError: UILabel!
  16. @IBOutlet weak var txtPasswordError: UILabel!
  17. @IBOutlet weak var progress: UIView!
  18. @IBOutlet weak var btnTogglePassword: UIButton!
  19. @IBOutlet weak var fullname: UILabel!
  20. @IBOutlet weak var btnOptionsRoles: UIButton!
  21. @IBOutlet weak var optionsRolesLayout: UIView!
  22. @IBOutlet weak var optionsTV: UITableView!
  23. @IBOutlet weak var imgDropdownOptionsRoles: UIImageView!
  24. // Initialize
  25. private var presenter: LoginPresenter!
  26. // Constant
  27. private let alertNoConnectionTitle = "Informasi"
  28. private let alertNoConnectionMsg = "Sepertinya Anda sedang tidak tersambung pada koneksi internet"
  29. private let alertNoConnectionActionYes = "OK"
  30. private let alertLoginFailedTitle = "Informasi"
  31. private let alertLoginFailedActionYes = "OK"
  32. private let urlResetPassword = "https://sertifikasi.postel.go.id/registrasi/forget"
  33. // private let urlRegister = "https://sertifikasi.postel.go.id/registrasi/daftar"
  34. private let urlRegister = "https://sertifikasi.postel.go.id/registrasi/daftar"
  35. private let urlRegisterOpen = "https://sertifikasi.postel.go.id/registrasi/forget"
  36. private let availableRoles = ["C","1","7","8","11"]
  37. private let CUSTOMER_ROLE_ID = "C"
  38. private let OPERATOR_ROLE_ID = "1"
  39. private let KEPALA_SEKSI_ROLE_ID = "7"
  40. private let KEPALA_SUB_DIREKTORAT_ROLE_ID = "11"
  41. private let DIREKTUR_ROLE_ID = "8"
  42. private let CUSTOMER_ROLE = "Customer"
  43. private let OPERATOR_ROLE = "Operator"
  44. private let KEPALA_SEKSI_ROLE = "Sub Koordinator"
  45. private let KEPALA_SUB_DIREKTORAT_ROLE = "Koordinator"
  46. private let DIREKTUR_ROLE = "Direktur"
  47. // Variables
  48. private var loading = false
  49. private var optionsRoles = [OptionItem]()
  50. // View Lifecycles
  51. override var preferredStatusBarStyle: UIStatusBarStyle {
  52. return .lightContent
  53. }
  54. override func viewWillAppear(_ animated: Bool) {
  55. presenter.attachView(view: self)
  56. checkUserState()
  57. }
  58. override func viewDidLoad() {
  59. super.viewDidLoad()
  60. presenter = LoginPresenter(siraniApiServices: SiraniApiServices())
  61. }
  62. override func viewDidDisappear(_ animated: Bool) {
  63. presenter.detachView()
  64. }
  65. // private functions
  66. private func checkUserState() {
  67. let isLoggedIn = UserState.instance.isLoggedIn()
  68. if isLoggedIn {
  69. showProfileLayout()
  70. } else {
  71. showLoginLayout()
  72. }
  73. }
  74. private func showLoginLayout() {
  75. inputUsername.text = ""
  76. inputPassword.text = ""
  77. loginLayout.show()
  78. profileLayout.hide()
  79. }
  80. private func showProfileLayout() {
  81. let name = UserState.instance.getFullname()
  82. fullname.text = name
  83. optionsRoles.removeAll()
  84. let userRoles = UserState.instance.getRoles()
  85. if !userRoles.isEmpty {
  86. let roles = userRoles.components(separatedBy: ";")
  87. for role in roles {
  88. if availableRoles.contains(role) {
  89. if role == CUSTOMER_ROLE_ID {
  90. let optionItem = OptionItem(label: CUSTOMER_ROLE, value: CUSTOMER_ROLE_ID)
  91. optionsRoles.append(optionItem)
  92. } else if role == OPERATOR_ROLE_ID {
  93. let optionItem = OptionItem(label: OPERATOR_ROLE, value: OPERATOR_ROLE_ID)
  94. optionsRoles.append(optionItem)
  95. } else if role == KEPALA_SEKSI_ROLE_ID {
  96. let optionItem = OptionItem(label: KEPALA_SEKSI_ROLE, value: KEPALA_SEKSI_ROLE_ID)
  97. optionsRoles.append(optionItem)
  98. } else if role == KEPALA_SUB_DIREKTORAT_ROLE_ID {
  99. let optionItem = OptionItem(label: KEPALA_SUB_DIREKTORAT_ROLE, value: KEPALA_SUB_DIREKTORAT_ROLE_ID)
  100. optionsRoles.append(optionItem)
  101. } else if role == DIREKTUR_ROLE_ID {
  102. let optionItem = OptionItem(label: DIREKTUR_ROLE, value: DIREKTUR_ROLE_ID)
  103. optionsRoles.append(optionItem)
  104. }
  105. }
  106. }
  107. btnOptionsRoles.layer.masksToBounds = false
  108. btnOptionsRoles.layer.shadowColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
  109. btnOptionsRoles.layer.shadowOpacity = 0.5
  110. btnOptionsRoles.layer.shadowOffset = CGSize(width: 1, height: 1)
  111. btnOptionsRoles.layer.shadowRadius = 1
  112. var selectedRole = "Pilih Role"
  113. let userRoleId = UserState.instance.getRoleId()
  114. if availableRoles.contains(userRoleId) {
  115. if userRoleId == CUSTOMER_ROLE_ID {
  116. selectedRole = CUSTOMER_ROLE
  117. } else if userRoleId == OPERATOR_ROLE_ID {
  118. selectedRole = OPERATOR_ROLE
  119. } else if userRoleId == KEPALA_SEKSI_ROLE_ID {
  120. selectedRole = KEPALA_SEKSI_ROLE
  121. } else if userRoleId == KEPALA_SUB_DIREKTORAT_ROLE_ID {
  122. selectedRole = KEPALA_SUB_DIREKTORAT_ROLE
  123. } else if userRoleId == DIREKTUR_ROLE_ID {
  124. selectedRole = DIREKTUR_ROLE
  125. }
  126. }
  127. btnOptionsRoles.setTitle(selectedRole, for: .normal)
  128. optionsTV.delegate = self
  129. optionsTV.dataSource = self
  130. optionsTV.tableFooterView = UIView()
  131. optionsTV.reloadData()
  132. if roles.count > 1 {
  133. btnOptionsRoles.show()
  134. imgDropdownOptionsRoles.show()
  135. } else {
  136. btnOptionsRoles.hide()
  137. imgDropdownOptionsRoles.hide()
  138. }
  139. } else {
  140. btnOptionsRoles.hide()
  141. imgDropdownOptionsRoles.hide()
  142. }
  143. profileLayout.show()
  144. loginLayout.hide()
  145. }
  146. private func inputValid(username: String, password: String) -> Bool {
  147. var valid = true
  148. if username.isEmpty {
  149. txtUsernameError.show()
  150. valid = false
  151. } else {
  152. txtUsernameError.hide()
  153. }
  154. if password.isEmpty {
  155. txtPasswordError.show()
  156. valid = false
  157. } else {
  158. txtPasswordError.hide()
  159. }
  160. return valid
  161. }
  162. private func login(username: String, password: String) {
  163. if !loading {
  164. if ConnectionHelper.isConnectedToNetwork() {
  165. ConnectionHelper.checkIpAddress { [weak self] success in
  166. guard let self = self else { return }
  167. DispatchQueue.main.async {
  168. if success {
  169. self.presenter.login(username: username, password: password)
  170. } else {
  171. CommonHelper.showNotAllowConnection(in: self)
  172. }
  173. }
  174. }
  175. } else {
  176. showNoConnection()
  177. }
  178. }
  179. }
  180. // Actions
  181. @IBAction func onBtnTogglePasswordTap(_ sender: Any) {
  182. let passHidden = inputPassword.isSecureTextEntry
  183. if passHidden {
  184. inputPassword.isSecureTextEntry = false
  185. btnTogglePassword.setImage(UIImage(named: "hide-password"), for: .normal)
  186. } else {
  187. inputPassword.isSecureTextEntry = true
  188. btnTogglePassword.setImage(UIImage(named: "show-password"), for: .normal)
  189. }
  190. }
  191. @IBAction func onBtnLoginTapped(_ sender: Any) {
  192. if !loading {
  193. let username = inputUsername.getText() ?? ""
  194. let password = inputPassword.getText() ?? ""
  195. if inputValid(username: username, password: password) {
  196. login(username: username, password: password)
  197. }
  198. }
  199. }
  200. // @IBAction func onBtnForgotPasswordTapped(_ sender: Any) {
  201. // if !loading {
  202. // //openWebPage(urlPage: urlResetPassword)
  203. //
  204. // if let url = URL(string: urlResetPassword) {
  205. // UIApplication.shared.open(url)
  206. // }
  207. //
  208. // }
  209. // }
  210. //
  211. // @IBAction func onBtnRegisterTapped(_ sender: Any) {
  212. // if !loading {
  213. // //openWebPage(urlPage: urlRegister)
  214. //
  215. // if let url = URL(string: urlRegister) {
  216. // UIApplication.shared.open(url)
  217. // }
  218. //
  219. // }
  220. // }
  221. @IBAction func onBtnOptionsRolesTap(_ sender: Any) {
  222. optionsRolesLayout.show()
  223. }
  224. @IBAction func onBtnLogoutTap(_ sender: Any) {
  225. showLoading()
  226. let isLoggedOut = UserState.instance.userDataCleared()
  227. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  228. self.hideLoading()
  229. if isLoggedOut {
  230. self.showLoginLayout()
  231. }
  232. }
  233. }
  234. @IBAction func onInputUsernameKeyTap(_ sender: Any) {
  235. inputPassword.becomeFirstResponder()
  236. }
  237. @IBAction func onInputPasswordKeyTap(_ sender: Any) {
  238. view.endEditing(true)
  239. }
  240. private func openWebPage(urlPage: String) {
  241. if let url = URL(string: urlPage) {
  242. if UIApplication.shared.canOpenURL(url) {
  243. if #available(iOS 10.0, *) {
  244. UIApplication.shared.open(url)
  245. } else {
  246. UIApplication.shared.openURL(url)
  247. }
  248. }
  249. }
  250. }
  251. private func showAlert(title: String, message: String, actionTitle: String) {
  252. let alertController = UIAlertController(
  253. title: title,
  254. message: message,
  255. preferredStyle: .alert)
  256. alertController.addAction(UIAlertAction(title: actionTitle, style: .default))
  257. self.present(alertController, animated: true, completion: nil)
  258. }
  259. }
  260. extension LoginVC: LoginViewDelegate {
  261. func showNoConnection() {
  262. let alertNoConnection = UIAlertController(
  263. title: alertNoConnectionTitle,
  264. message: alertNoConnectionMsg,
  265. preferredStyle: .alert
  266. )
  267. alertNoConnection.addAction(
  268. UIAlertAction(title: alertNoConnectionActionYes, style: .default, handler: nil)
  269. )
  270. self.present(alertNoConnection, animated: true, completion: nil)
  271. }
  272. func showLoading() {
  273. loading = true
  274. progress.show()
  275. }
  276. func hideLoading() {
  277. loading = false
  278. progress.hide()
  279. }
  280. func onFailedLogin(message: String) {
  281. let alertLoginFailed = UIAlertController(
  282. title: alertLoginFailedTitle,
  283. message: message,
  284. preferredStyle: .alert
  285. )
  286. alertLoginFailed.addAction(
  287. UIAlertAction(title: alertLoginFailedActionYes, style: .default, handler: nil)
  288. )
  289. self.present(alertLoginFailed, animated: true, completion: nil)
  290. }
  291. func onSuccessLogin(user: User) {
  292. debugPrint(user)
  293. showProfileLayout()
  294. }
  295. }
  296. extension LoginVC: UITableViewDelegate, UITableViewDataSource {
  297. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  298. return optionsRoles.count
  299. }
  300. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  301. if let cell = tableView.dequeueReusableCell(withIdentifier: "AccountOptionCell", for: indexPath) as? OptionsCell {
  302. let optionItem = optionsRoles[indexPath.row]
  303. cell.updateViews(item: optionItem)
  304. return cell
  305. } else {
  306. return OptionsCell()
  307. }
  308. }
  309. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  310. var selectedRole = "Pilih Role"
  311. let selectedRoleId = optionsRoles[indexPath.row].value as! String
  312. if availableRoles.contains(selectedRoleId) {
  313. if selectedRoleId == CUSTOMER_ROLE_ID {
  314. selectedRole = CUSTOMER_ROLE
  315. } else if selectedRoleId == OPERATOR_ROLE_ID {
  316. selectedRole = OPERATOR_ROLE
  317. } else if selectedRoleId == KEPALA_SEKSI_ROLE_ID {
  318. selectedRole = KEPALA_SEKSI_ROLE
  319. } else if selectedRoleId == KEPALA_SUB_DIREKTORAT_ROLE_ID {
  320. selectedRole = KEPALA_SUB_DIREKTORAT_ROLE
  321. } else if selectedRoleId == DIREKTUR_ROLE_ID {
  322. selectedRole = DIREKTUR_ROLE
  323. }
  324. }
  325. let saved = UserState.instance.saveRoleId(roleId: selectedRoleId)
  326. if saved {
  327. btnOptionsRoles.setTitle(selectedRole, for: .normal)
  328. optionsRolesLayout.hide()
  329. } else {
  330. btnOptionsRoles.setTitle(selectedRole, for: .normal)
  331. optionsRolesLayout.hide()
  332. }
  333. }
  334. }