Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.61 KB | None | 0 0
  1. //
  2. // BestOffersViewController.swift
  3. // finance
  4. //
  5. // Created by David Yanez on 4/2/18.
  6. // Copyright © 2018 creditsesame. All rights reserved.
  7. //
  8.  
  9. import UIKit
  10. import SnapKit
  11.  
  12. enum OffersTab: String {
  13. case creditCards = "CCs"
  14. case personalLoans = "PLs"
  15. }
  16.  
  17. class BestOffersViewController: OffersViewController, UITableViewDelegate, UITableViewDataSource {
  18.  
  19. let ccHeaderIdentifier = "BestCardsHeaderView"
  20. let notFoundIdentifier = "notFoundCellIdentifier"
  21. let pLHeaderIdentifier = "BestPersonalLoanHeaderView"
  22. let footerIdentifier = "MoreCardsFooter"
  23. let newMoreCardsButton = "NewMoreCardsButton"
  24. let dismissViewTag = 989898
  25.  
  26. var bestCards: [CreditCard]?
  27. var creditCardSections: [[CreditCard]] = []
  28. var personalLoan: PersonalLoan?
  29. var offersHeaderView: UIView!
  30. var currentTab: OffersTab = .creditCards
  31. var previousPLCallWasEmptyNoErrors = false
  32. var inputError: Bool {
  33. return incomeInputError || amountInputError
  34. }
  35. var incomeInputError = false
  36. var amountInputError = false
  37.  
  38. var loanAmount: Int {
  39. get {
  40. return AppContext.shared.pLAmountNeeded
  41. }
  42. set {
  43. AppContext.shared.pLAmountNeeded = newValue
  44. }
  45. }
  46.  
  47. var loanAmountTextField: UITextField?
  48. var annualIncomeTextField: UITextField?
  49. var timer: CSTimer?
  50.  
  51. override var screeName: String {
  52. get {
  53. return currentTab == .creditCards ? AnalyticsScreenName.ccOffers : AnalyticsScreenName.plOffers
  54. }
  55. }
  56.  
  57. let filters: [FilterData] = [FilterData(title: " Best Cards", imageName: "star_bestCards"), FilterData(title: " Cash Back", imageName: "cash_cashBack"), FilterData(title: " No Annual Fee", imageName: "calendar_noAnnualFee"), FilterData(title: " 0% Intro Purchase APR", imageName: "shopping_oapr"), FilterData(title: " Rewards", imageName: "palmTrees_rewards"), FilterData(title: " Balance Transfer", imageName: "pig_balanceTransfer")
  58. ]
  59.  
  60. var lastFilterSelected: Int {
  61. get {
  62. return UserDefaults.standard.integer(forKey: "lastFilterSelected")
  63. }
  64. set {
  65. UserDefaults.standard.set(newValue, forKey: "lastFilterSelected")
  66. UserDefaults.standard.synchronize()
  67. }
  68. }
  69.  
  70. override func viewDidLoad() {
  71. super.viewDidLoad()
  72. edgesForExtendedLayout = []
  73. tableView.register(UINib(nibName: ccHeaderIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: ccHeaderIdentifier)
  74. tableView.register(UINib(nibName: pLHeaderIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: pLHeaderIdentifier)
  75. tableView.register(UINib(nibName: footerIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: footerIdentifier)
  76. tableView.register(UINib(nibName: newMoreCardsButton, bundle: nil), forHeaderFooterViewReuseIdentifier: newMoreCardsButton)
  77. tableView.register(UITableViewCell.self, forCellReuseIdentifier: notFoundIdentifier)
  78.  
  79. tableView.estimatedRowHeight = 300
  80. tableView.rowHeight = UITableView.automaticDimension
  81. tableView.estimatedSectionHeaderHeight = 300
  82. tableView.sectionHeaderHeight = UITableView.automaticDimension
  83. tableView.estimatedSectionFooterHeight = 36
  84. tableView.separatorStyle = .singleLine
  85. tableView.separatorColor = .white
  86. tableView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  87. configureStatusBar(color: UIColor.white)
  88.  
  89. if TestingManager.shared.newCCFilteringVariation == Variations.control {
  90. loadData(index: 0)
  91. configureFooter()
  92. } else {
  93. loadData(index: lastFilterSelected)
  94. }
  95.  
  96. configureHeader()
  97.  
  98. }
  99.  
  100. override func scrollToTop() {
  101. tableView?.setContentOffset(.zero, animated: true)
  102. }
  103.  
  104. func configureHeader() {
  105. offersHeaderView = UIView.loadNib("OffersHeaderView")
  106. offersHeaderView.backgroundColor = UIColor.white
  107. let titleLabel = offersHeaderView.labelWithTag(20)
  108. let descriptionLabel = offersHeaderView.labelWithTag(21)
  109. let ccButton = offersHeaderView.buttonWithTag(31)
  110. let pLButton = offersHeaderView.buttonWithTag(41)
  111. titleLabel?.font = UIFont.latoHeavy(20)
  112. titleLabel?.textColor = UIColor.creditSesameGrayTextColor
  113. titleLabel?.text = NSLocalizedString("Your Borrowing Power", comment: "Your Borrowing Power")
  114.  
  115. let textDescription = NSLocalizedString("CreditCardBorrowingPowerDescription", comment: "card borrowing description")
  116. let boldText = NSLocalizedString("credit profile", comment: "credit profile text")
  117. let attributedDescription = NSMutableAttributedString(string: textDescription, attributes: [NSAttributedString.Key.font : UIFont.lato(16), NSAttributedString.Key.foregroundColor : UIColor.creditSesameDarkTextColor])
  118. attributedDescription.addAttributes([NSAttributedString.Key.font : UIFont.latoBold(16)], range: (textDescription as NSString).range(of: boldText))
  119. descriptionLabel?.attributedText = attributedDescription
  120. descriptionLabel?.numberOfLines = 0
  121. descriptionLabel?.lineBreakMode = .byWordWrapping
  122.  
  123. let height = offersHeaderView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
  124. let headerView = UITableViewHeaderFooterView(frame: CGRect(x: 0, y: 0, width: 0, height: height))
  125. headerView.backgroundColor = UIColor.clear
  126.  
  127. if TestingManager.shared.newCCFilteringVariation == Variations.control {
  128. let topView = UIView()
  129. let segmentControl = DGScrollableSegmentControl()
  130. let stackView = offersHeaderView.viewWithTag(40) as! UIStackView
  131.  
  132. topView.heightAnchor.constraint(equalToConstant: 16).isActive = true
  133. segmentControl.heightAnchor.constraint(equalToConstant: 32).isActive = true
  134. topView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  135. topView.addTopSeparator()
  136. segmentControl.delegate = self
  137. segmentControl.datasource = self
  138.  
  139. stackView.addArrangedSubview(topView)
  140. stackView.addArrangedSubview(segmentControl)
  141. }
  142.  
  143. headerView.addSubview(offersHeaderView)
  144. offersHeaderView.clipsToBounds = true
  145. offersHeaderView.snp.makeConstraints { (make) in
  146. make.edges.equalToSuperview()
  147. }
  148.  
  149. let selectedttributtes = [NSAttributedString.Key.font : UIFont.lato(16),
  150. NSAttributedString.Key.foregroundColor : UIColor.creditSesameCyan,
  151. NSAttributedString.Key.kern : 0.5] as [NSAttributedString.Key : Any]
  152.  
  153. let unselectedAttributtes = [NSAttributedString.Key.font : UIFont.lato(16),
  154. NSAttributedString.Key.foregroundColor : UIColor.init(rgb: 0x757575),
  155. NSAttributedString.Key.kern : 0.5] as [NSAttributedString.Key : Any]
  156.  
  157. let creditTitle = NSAttributedString(string: NSLocalizedString("Credit Cards", comment: "credit cards button"), attributes: selectedttributtes)
  158. let creditTitleUnSelected = NSAttributedString(string: creditTitle.string, attributes: unselectedAttributtes)
  159. ccButton?.setAttributedTitle(creditTitle, for: .selected)
  160. ccButton?.setAttributedTitle(creditTitleUnSelected, for: .normal)
  161. ccButton?.isSelected = true
  162. ccButton?.addTarget(self, action: #selector(switchToCards), for: .touchUpInside)
  163.  
  164. let debtTitle = NSAttributedString(string: NSLocalizedString("Personal Loans", comment: "personal loans button"), attributes: selectedttributtes)
  165. let debtTitleUnSelected = NSAttributedString(string: debtTitle.string, attributes: unselectedAttributtes)
  166. pLButton?.setAttributedTitle(debtTitleUnSelected, for: .normal)
  167. pLButton?.setAttributedTitle(debtTitle, for: .selected)
  168. pLButton?.backgroundColor = UIColor.clear
  169. pLButton?.isSelected = false
  170. pLButton?.addTarget(self, action: #selector(switchToPLs), for: .touchUpInside)
  171.  
  172. let button = offersHeaderView.buttonWithTag(10)
  173. button?.setThemeAdvertiserDisclosure()
  174. button?.backgroundColor = UIColor.clear
  175. button?.addTarget(self, action: #selector(showAdvertisersDisclosureTooltip), for: .touchUpInside)
  176.  
  177. tableView.tableHeaderView = headerView
  178. }
  179.  
  180. func disclosureFooterView() -> DisclosureFooterView {
  181. let disclosureFooterView = DisclosureFooterView()
  182. disclosureFooterView.providerTermsPressed = { [weak self] in
  183. self?.showProviderTermsDisclosureTooltip()
  184. }
  185. disclosureFooterView.editorialDisclosurePressed = { [weak self] in
  186. self?.showEditorialDisclosureTooltip()
  187.  
  188. }
  189.  
  190. return disclosureFooterView
  191. }
  192.  
  193. func configureFooter() {
  194.  
  195. if currentTab == .personalLoans {
  196. tableView.tableFooterView = nil
  197. return
  198. }
  199.  
  200. let offersFooterView = UIView.loadNib("OffersFooterView")
  201. offersFooterView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  202. let balanceButton = offersFooterView.buttonWithTag(11)!
  203. balanceButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside)
  204. balanceButton.accessibilityLabel = NSLocalizedString("Balance Transfer", comment: "BT Cards Header")
  205. let zeroPercentButton = offersFooterView.buttonWithTag(12)!
  206. zeroPercentButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside)
  207. zeroPercentButton.accessibilityLabel = NSLocalizedString("ZeroPurchaseAPR", comment: "0% Intro Purchase APR Header")
  208. let rewardsButton = offersFooterView.buttonWithTag(13)!
  209. rewardsButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside)
  210. rewardsButton.accessibilityLabel = NSLocalizedString("Rewards", comment: "Rewards Cards Header")
  211.  
  212. let titleLabel = offersFooterView.labelWithTag(10)
  213. titleLabel?.font = UIFont.latoBold(20)
  214. titleLabel?.textColor = UIColor.creditSesameDarkTextColor
  215. titleLabel?.text = NSLocalizedString("Credit Card Categories", comment: "Footer categories")
  216. let height = offersFooterView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
  217. let footerView = UITableViewHeaderFooterView(frame: CGRect(x: 0, y: 0, width: 0, height: height))
  218. footerView.backgroundColor = UIColor.clear
  219. footerView.addSubview(offersFooterView)
  220. offersFooterView.clipsToBounds = true
  221. offersFooterView.snp.makeConstraints { (make) in
  222. make.edges.equalToSuperview()
  223. }
  224.  
  225. let disclosureContainerView = offersFooterView.viewWithTag(14)
  226. let disclosureView = disclosureFooterView()
  227. disclosureContainerView?.addSubview(disclosureView)
  228. disclosureView.snp.makeConstraints { make in
  229. make.edges.equalToSuperview()
  230. }
  231.  
  232. tableView.tableFooterView = footerView
  233. }
  234.  
  235. func loadPersonalLoanIfNeeded(isInputChange: Bool = false) {
  236.  
  237. let currentIncome = CreditSesameRestClient.shared.user?.annualIncome
  238. let currentAmount = AppContext.shared.pLAmountNeeded
  239. // update income and amount if they did change
  240. var needsNewPLFromServer = false
  241. if let income = annualIncomeTextField?.text?.removeMoneyFormat() {
  242. if let userIncome = currentIncome, income.doubleValue != userIncome.doubleValue {
  243. let newIncome = isInputChange ? income : userIncome
  244. annualIncomeTextField?.text = String.moneyFormattedString(number: newIncome)
  245. incomeInputError = false
  246. needsNewPLFromServer = true
  247. }
  248. }
  249. if let amount = loanAmountTextField?.text?.removeMoneyFormat() {
  250. if amount.intValue != currentAmount {
  251. let newAmount = isInputChange ? amount : NSNumber(value: currentAmount)
  252. loanAmountTextField?.text = String.moneyFormattedString(number: newAmount)
  253. amountInputError = false
  254. needsNewPLFromServer = true
  255. }
  256. }
  257.  
  258. if (personalLoan != nil || (personalLoan == nil && previousPLCallWasEmptyNoErrors && !inputError)) && !needsNewPLFromServer {
  259. self.tableView.reloadData()
  260. self.configureFooter()
  261. return
  262. }
  263.  
  264. let annualIncome = annualIncomeTextField?.text?.removeMoneyFormat().intValue ?? CreditSesameRestClient.shared.user?.annualIncome?.intValue ?? 0
  265. let amount = loanAmountTextField?.text?.removeMoneyFormat().intValue ?? loanAmount
  266.  
  267. showProgressView()
  268.  
  269. CreditSesameRestClient.shared.getAllPersonalLoans(loanAmount: amount, annualIncome: annualIncome, page: 1, itemsPerPage: 10) { (personalLoans, error) in
  270. self.hideProgressView()
  271.  
  272. if let _ = error {
  273. self.personalLoan = nil
  274. self.previousPLCallWasEmptyNoErrors = false
  275. }
  276. else if let personalLoans = personalLoans, personalLoans.count > 0 {
  277. self.personalLoan = personalLoans.first
  278. self.previousPLCallWasEmptyNoErrors = false
  279. }
  280. else {
  281. self.personalLoan = nil
  282. self.previousPLCallWasEmptyNoErrors = true
  283. }
  284. self.tableView.reloadData()
  285. self.configureFooter()
  286. }
  287. }
  288.  
  289. override func keyboardWillShow(_ notification: Notification) {
  290. super.keyboardWillShow(notification)
  291.  
  292. if view.viewWithTag(dismissViewTag) == nil {
  293. let dismissView = UIView()
  294. let dismissTapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView(_:)))
  295. dismissView.tag = dismissViewTag
  296. dismissView.backgroundColor = UIColor.clear
  297. dismissView.addGestureRecognizer(dismissTapGesture)
  298. view.addSubview(dismissView)
  299. dismissView.snp.makeConstraints { make in
  300. make.edges.equalToSuperview()
  301. }
  302. }
  303. }
  304.  
  305. override func keyboardWillHide(_ notification: Notification) {
  306. super.keyboardWillHide(notification)
  307.  
  308. if let v = view.viewWithTag(dismissViewTag) {
  309. v.removeFromSuperview()
  310. }
  311. }
  312.  
  313. @objc func switchToCards() {
  314.  
  315. if currentTab == .creditCards {
  316. return
  317. }
  318.  
  319. let ccButton = offersHeaderView.buttonWithTag(31)
  320. let ccBorderView = offersHeaderView.viewWithTag(32)
  321. let pLButton = offersHeaderView.buttonWithTag(41)
  322. let pLBorderView = offersHeaderView.viewWithTag(42)
  323.  
  324. ccButton?.isSelected = true
  325. ccBorderView?.isHidden = false
  326. pLButton?.isSelected = false
  327. pLBorderView?.isHidden = true
  328.  
  329. currentTab = .creditCards
  330. tableView.reloadData()
  331. configureFooter()
  332. trackViewPage()
  333. }
  334.  
  335. @objc func switchToPLs() {
  336.  
  337. if currentTab == .personalLoans {
  338. return
  339. }
  340.  
  341. let ccButton = offersHeaderView.buttonWithTag(31)
  342. let ccBorderView = offersHeaderView.viewWithTag(32)
  343. let pLButton = offersHeaderView.buttonWithTag(41)
  344. let pLBorderView = offersHeaderView.viewWithTag(42)
  345.  
  346. ccButton?.isSelected = false
  347. ccBorderView?.isHidden = true
  348. pLButton?.isSelected = true
  349. pLBorderView?.isHidden = false
  350.  
  351. currentTab = .personalLoans
  352. loadPersonalLoanIfNeeded()
  353. trackViewPage()
  354. }
  355.  
  356. @objc func browseCategories(button: UIButton) {
  357.  
  358. switch button.tag {
  359. case 11:
  360.  
  361. let cards = CreditSesameRestClient.shared.balanceTransferCards ?? []
  362. self.openCreditCards(screen: .bestCardsBT, creditCards: cards)
  363. trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsBT)
  364. case 12:
  365.  
  366. let cards = CreditSesameRestClient.shared.zeroPercentCards ?? []
  367. self.openCreditCards(screen: .bestCardsZeroPercent, creditCards: cards)
  368. trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsZeroPercent)
  369. case 13:
  370.  
  371. let cards = CreditSesameRestClient.shared.rewardsCards ?? []
  372. self.openCreditCards(screen: .bestCardsRewards, creditCards: cards)
  373. trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsRewards)
  374. default:
  375. break
  376. }
  377. }
  378.  
  379. @objc func viewMoreCards(button: UIButton) {
  380. openCreditCardsMarketplace()
  381. }
  382.  
  383. @objc func editAmount() {
  384. loanAmountTextField?.becomeFirstResponder()
  385. }
  386.  
  387. @objc func editIncome() {
  388. annualIncomeTextField?.becomeFirstResponder()
  389. }
  390.  
  391. override func viewWillAppear(_ animated: Bool) {
  392. super.viewWillAppear(animated)
  393. navigationController?.setNavigationBarHidden(true, animated: true)
  394. creditSesameNavigationController?.setNavigationBarHidden(true, animated: true)
  395. }
  396.  
  397. override func viewDidAppear(_ animated: Bool) {
  398. super.viewDidAppear(animated)
  399.  
  400.  
  401.  
  402. if currentTab == .personalLoans {
  403. self.loadPersonalLoanIfNeeded()
  404. }
  405. }
  406.  
  407. func loadData(index: Int) {
  408. switch index {
  409. case 0:
  410. creditCardSections = [CreditSesameRestClient.shared.bestCards ?? []]
  411. self.tableView.reloadData()
  412. self.configureFooter()
  413. case 1:
  414. creditCardSections = [CreditSesameRestClient.shared.cashBackCards ?? []]
  415. self.tableView.reloadData()
  416. self.configureFooter()
  417. case 2:
  418. creditCardSections = [CreditSesameRestClient.shared.noAnnualFeeCards ?? []]
  419. self.tableView.reloadData()
  420. self.configureFooter()
  421. case 3:
  422. creditCardSections = [CreditSesameRestClient.shared.zeroPercentCards ?? []]
  423. self.tableView.reloadData()
  424. self.configureFooter()
  425. case 4:
  426. creditCardSections = [CreditSesameRestClient.shared.rewardsCards ?? []]
  427. self.tableView.reloadData()
  428. self.configureFooter()
  429. case 5:
  430. creditCardSections = [CreditSesameRestClient.shared.balanceTransferCards ?? []]
  431. self.tableView.reloadData()
  432. self.configureFooter()
  433. default:
  434. creditCardSections = [CreditSesameRestClient.shared.bestCards ?? []]
  435. self.tableView.reloadData()
  436. self.configureFooter()
  437. }
  438. }
  439.  
  440. func getPagePosition(_ lastFilterSelected: Int) -> String {
  441. switch lastFilterSelected {
  442. case 0:
  443. return AnalyticsPagePosition.bestCards
  444. case 1:
  445. return AnalyticsPagePosition.cashBack
  446. case 2:
  447. return AnalyticsPagePosition.noAnnualFee
  448. case 3:
  449. return AnalyticsPagePosition.introPurchaseAPR
  450. case 4:
  451. return AnalyticsPagePosition.rewards
  452. case 5:
  453. return AnalyticsPagePosition.balanceTransfer
  454. default:
  455. return AnalyticsPagePosition.bestCards
  456. }
  457. }
  458.  
  459. func numberOfSections(in tableView: UITableView) -> Int {
  460. return 1
  461. }
  462.  
  463. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  464. switch currentTab {
  465. case .creditCards:
  466. let cards = creditCardSections[section]
  467. return min(3, cards.count)
  468. case .personalLoans:
  469. return 1
  470. }
  471. }
  472.  
  473. func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  474. switch currentTab {
  475. case .creditCards:
  476. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ccHeaderIdentifier)
  477. let backgroundView = view?.viewWithTag(10)
  478. let label = view?.labelWithTag(11)
  479.  
  480. backgroundView?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  481.  
  482. label?.font = UIFont.latoBlack(20)
  483. label?.textColor = UIColor.creditSesameDarkTextColor
  484.  
  485. let attributedText = NSMutableAttributedString(string: NSLocalizedString("Best Cards", comment: "Best Cards Cards Header"), attributes:
  486. [NSAttributedString.Key.foregroundColor : UIColor.init(rgb: 0x929292),
  487. NSAttributedString.Key.font : UIFont.lato(20)])
  488. attributedText.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.creditSesameGrayTextColor,
  489. NSAttributedString.Key.font : UIFont.latoHeavy(20)], range: (attributedText.string as NSString).range(of: "Best Cards"))
  490. label?.attributedText = attributedText
  491. view?.addTopSeparator()
  492. if TestingManager.shared.newCCFilteringVariation == Variations.variation {
  493. return nil
  494. } else {
  495. return view
  496. }
  497.  
  498. case .personalLoans:
  499. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: pLHeaderIdentifier)
  500. let amountLabel = view?.labelWithTag(21)
  501. let amountView = view?.viewWithTag(200)
  502. let amountTextField = view?.textFieldWithTag(22) as? TextField
  503. let amountTooltip = view?.buttonWithTag(23)
  504. let incomeLabel = view?.labelWithTag(31)
  505. let incomeView = view?.viewWithTag(300)
  506. let incomeTextField = view?.textFieldWithTag(32) as? TextField
  507. let incomeTooltip = view?.buttonWithTag(33)
  508.  
  509. let amountNumber = loanAmountTextField?.text?.removeMoneyFormat() ?? NSNumber(value: loanAmount)
  510. let annualIncome = annualIncomeTextField?.text?.removeMoneyFormat() ?? CreditSesameRestClient.shared.user?.annualIncome ?? NSNumber(value: 0)
  511.  
  512. amountLabel?.font = UIFont.lato(16)
  513. amountLabel?.textColor = UIColor.creditSesameGrayTextColor
  514. amountLabel?.text = NSLocalizedString("Loan Amount", comment: "loan amount label")
  515. amountTextField?.text = String.moneyFormattedString(number: amountNumber)
  516. amountTextField?.font = UIFont.latoMedium(16)
  517. amountTextField?.textColor = UIColor.black
  518. amountTextField?.keyboardType = .numberPad
  519. amountTextField?.delegate = self
  520. amountTextField?.maxCharacters = 6
  521. amountView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor
  522. amountView?.layer.borderWidth = 1
  523. loanAmountTextField = amountTextField
  524. amountTooltip?.addTarget(self, action: #selector(showPLAmountTooltip), for: .touchUpInside)
  525.  
  526. amountView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editAmount)))
  527.  
  528. incomeLabel?.font = UIFont.lato(16)
  529. incomeLabel?.textColor = UIColor.creditSesameGrayTextColor
  530. incomeLabel?.text = NSLocalizedString("Annual Income", comment: "income label")
  531. incomeTextField?.text = String.moneyFormattedString(number: annualIncome)
  532. incomeTextField?.font = UIFont.latoMedium(16)
  533. incomeTextField?.textColor = UIColor.black
  534. incomeTextField?.keyboardType = .numberPad
  535. incomeTextField?.delegate = self
  536. incomeTextField?.maxCharacters = 7
  537. incomeView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor
  538. incomeView?.layer.borderWidth = 1
  539. annualIncomeTextField = incomeTextField
  540. incomeTooltip?.addTarget(self, action: #selector(showPLIncomeTooltip), for: .touchUpInside)
  541.  
  542. incomeView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editIncome)))
  543.  
  544. return view
  545. }
  546.  
  547. }
  548.  
  549. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
  550. return currentTab == .creditCards ? (TestingManager.shared.newCCFilteringVariation == Variations.variation ? 72 : 36) : 60
  551. }
  552.  
  553. func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  554. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerIdentifier)
  555. let actionView = view?.viewWithTag(100)
  556. let button = view?.buttonWithTag(10)
  557. let line = view?.viewWithTag(11)
  558. line?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  559. button?.setTitleColor(UIColor.creditSesameCyan, for: .normal)
  560. button?.titleLabel?.font = UIFont.lato(14)
  561. view?.backgroundColor = UIColor.white
  562. actionView?.addTopSeparator()
  563. actionView?.addBottomSeparator()
  564.  
  565. switch currentTab {
  566. case .creditCards:
  567.  
  568. if TestingManager.shared.newCCFilteringVariation == Variations.variation {
  569. return newMoreFooterView
  570. }
  571. button?.setTitle(NSLocalizedString("See All Credit Cards", comment: "More Cards button"), for: .normal)
  572. button?.superview?.tag = section
  573. button?.removeTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside)
  574. button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  575.  
  576. case .personalLoans:
  577. guard let _ = personalLoan else {
  578. return nil
  579. }
  580. button?.setTitle(NSLocalizedString("See More Personal Loans", comment: "More Cards button"), for: .normal)
  581. button?.removeTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  582. button?.addTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside)
  583.  
  584. }
  585.  
  586. return view
  587.  
  588. }
  589.  
  590. var newMoreFooterView: UIView? {
  591. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: newMoreCardsButton)
  592. let button = view?.buttonWithTag(10)
  593. button?.setTitleColor(UIColor.white, for: .normal)
  594. button?.titleLabel?.font = UIFont.latoSemiBold(13)
  595. button?.backgroundColor = UIColor.creditSesameCyan
  596. button?.setTitle(NSLocalizedString("Search All Credit Cards", comment: "More Cards"), for: .normal)
  597. view?.addTopSeparator()
  598. button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  599. return view
  600. }
  601.  
  602. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  603. switch currentTab {
  604. case .creditCards:
  605. let creditCards = creditCardSections[indexPath.section]
  606. let creditCard = creditCards[indexPath.row]
  607. var creditCardCell: ClickApplyCell? = nil
  608. var pagePosition: String
  609. pagePosition = AnalyticsPagePosition.bestCards
  610. if TestingManager.shared.newCCFilteringVariation == Variations.control {
  611. pagePosition = getPagePosition(lastFilterSelected)
  612. }
  613. creditCardCell = cellForCreditCard(creditCard: creditCard, offerType: .estimatedCreditLimit)
  614. creditCardCell?.contentView.tag = indexPath.row
  615.  
  616. let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1
  617. creditCardCell?.cellPosition = "\(offerPosition)"
  618. creditCardCell?.pagePosition = pagePosition
  619. creditCardCell?.offer = creditCard
  620. creditCardCell?.selectionStyle = .none
  621. creditCardCell?.addTopSeparator()
  622.  
  623. trackViewOfferCreditCard(creditCard: creditCard, pagePosition: pagePosition, pageLocation: nil, offerPosition: creditCardCell?.cellPosition!)
  624. return creditCardCell!
  625.  
  626. case .personalLoans:
  627. if let loan = personalLoan {
  628. let personalLoanCell = cellForPersonalLoan(pL: loan, offerType: loan.offerType)
  629. let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1
  630. personalLoanCell.cellPosition = "\(offerPosition)"
  631. personalLoanCell.pagePosition = nil
  632. personalLoanCell.pageLocation = nil
  633. personalLoanCell.offer = loan
  634. personalLoanCell.selectionStyle = .none
  635.  
  636. trackViewOfferPersonalLoan(personalLoan: personalLoan!, pagePosition: nil, pageLocation: nil, offerPosition: "1")
  637. return personalLoanCell
  638. }
  639. else if let cell = tableView.dequeueReusableCell(withIdentifier: notFoundIdentifier) {
  640.  
  641. for v in cell.contentView.subviews {
  642. v.removeFromSuperview()
  643. }
  644.  
  645. let view = UIView.loadNib("OffersNotFoundView")
  646. let titleLabel = view.labelWithTag(10)
  647. let contentLabel = view.labelWithTag(11)
  648. let actionView = view.viewWithTag(20)
  649. let actionButton = view.buttonWithTag(21)
  650. let accessibilityView = view.viewWithTag(30)!
  651.  
  652. titleLabel?.font = UIFont.latoHeavy(18)
  653. titleLabel?.textColor = UIColor.init(rgb: 0x606060)
  654. titleLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundTitle ?? NSLocalizedString("Loans Offer Not Found title", comment: "Not found title")
  655. contentLabel?.font = UIFont.lato(14)
  656. contentLabel?.textColor = UIColor.init(rgb: 0x606060)
  657. contentLabel?.textAlignment = .left
  658. contentLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundContent ?? NSLocalizedString("Loans Offer Not Found content", comment: "Not found content")
  659. contentLabel?.numberOfLines = 0
  660. contentLabel?.lineBreakMode = .byWordWrapping
  661.  
  662. actionView?.isHidden = false
  663. let buttonTitle = currentTab == .creditCards ? NSLocalizedString("Search All Credit Cards", comment: "Market place button") : NSLocalizedString("Search All Personal Loans", comment: "Market place button")
  664. actionButton?.setThemeInfoButton(title: buttonTitle)
  665. let selector = currentTab == .creditCards ? #selector(openCreditCardsMarketplace) : #selector(openPersonalLoansMarketplace)
  666. actionButton?.addTarget(self, action: selector, for: .touchUpInside)
  667.  
  668. cell.contentView.addSubview(view)
  669. view.snp.makeConstraints({ make in
  670. make.edges.equalToSuperview()
  671. })
  672.  
  673. cell.selectionStyle = .none
  674. cell.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  675.  
  676. accessibilityView.isAccessibilityElement = true
  677. accessibilityView.accessibilityLabel = "\(titleLabel?.text ?? ""): \(contentLabel?.text ?? "")"
  678.  
  679. return cell
  680. }
  681. }
  682.  
  683. return UITableViewCell()
  684. }
  685.  
  686. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  687. tableView.deselectRow(at: indexPath, animated: true)
  688. }
  689.  
  690. }
  691.  
  692. extension BestOffersViewController: UITextFieldDelegate {
  693.  
  694. func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
  695. textField.text = "\(textField.text?.removeMoneyFormat().intValue ?? 0)"
  696.  
  697. if textField == self.loanAmountTextField {
  698. trackClick(clickType: AnalyticsClickType.enterLoanAmount, pagePosition: nil)
  699. }
  700.  
  701. // update annual income
  702. if textField == self.annualIncomeTextField {
  703. trackClick(clickType: AnalyticsClickType.updateIncome, pagePosition: nil)
  704. }
  705.  
  706. return true
  707. }
  708.  
  709. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  710.  
  711. let currentString = textField.text! as NSString
  712. let newString = currentString.replacingCharacters(in: range, with: string) as NSString
  713.  
  714. if let textField = textField as? TextField, let maxLength = textField.maxCharacters, newString.length > maxLength {
  715. return false
  716. }
  717.  
  718. if let timer = timer {
  719. timer.startTimer()
  720. }
  721. else {
  722. timer = CSTimer()
  723. timer?.action = {
  724.  
  725. if (self.annualIncomeTextField?.text?.count ?? 0) == 0 || (self.loanAmountTextField?.text?.count ?? 0) == 0 {
  726. return
  727. }
  728.  
  729. self.loadPersonalLoanIfNeeded(isInputChange: true)
  730. DispatchQueue.main.async {
  731. self.hideKeyboard()
  732. }
  733. }
  734. timer?.startTimer()
  735. }
  736. return true
  737. }
  738.  
  739. func textFieldDidEndEditing(_ textField: UITextField) {
  740. let money = textField.text?.removeMoneyFormat().doubleValue ?? 0
  741.  
  742. // update amount needed
  743. if textField == self.loanAmountTextField {
  744. guard money >= 0 && money <= 100000 else {
  745. let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorLoanAmount ?? NSLocalizedString("AmountNeededTooltip", comment: "amount loan error")
  746. showAppClientError(message)
  747. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  748. amountInputError = true
  749. return
  750. }
  751. amountInputError = false
  752. loanAmount = Int(money)
  753. }
  754.  
  755. // update annual income
  756. if textField == self.annualIncomeTextField {
  757. guard money > 0 else {
  758. let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorAnnualIncome ?? NSLocalizedString("CalculateDTIIncomeError", comment: "invalid income error")
  759. showAppClientError(message)
  760. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  761. incomeInputError = true
  762. return
  763. }
  764.  
  765. incomeInputError = false
  766. let user = CreditSesameRestClient.shared.user?.copy() as? User ?? User()
  767. if user.annualIncome?.doubleValue != money {
  768. user.annualIncome = NSNumber(value: money)
  769. CreditSesameRestClient.shared.updateUser(user: user, password: AppContext.shared.password)
  770. }
  771. }
  772.  
  773. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  774. }
  775. }
  776.  
  777. extension BestOffersViewController: DGScrollableSegmentControlDataSource,DGScrollableSegmentControlDelegate {
  778.  
  779.  
  780. func numbersOfItem() -> Int {
  781. return filters.count
  782. }
  783.  
  784. func itemfor(_ index: Int) -> DGItem {
  785.  
  786. let item = DGItem()
  787. item.setTitle(filters[index].title, for: .normal)
  788. item.isSelected = index == lastFilterSelected
  789. item.setImage(UIImage(named: filters[index].imageName), for: .normal)
  790. item.titleLabel?.font = UIFont.latoSemiBold(12)
  791.  
  792. if item.isSelected {
  793. item.setTitleColor(UIColor.white, for: .normal)
  794. item.backgroundColor = UIColor.creditSesameCyan
  795. } else {
  796. item.setTitleColor(UIColor.creditSesameCyan, for: .normal)
  797. item.backgroundColor = UIColor.white
  798. }
  799.  
  800. return item
  801.  
  802. }
  803.  
  804. func didSelect(_ item: DGItem, atIndex index: Int) {
  805. lastFilterSelected = index
  806. loadData(index: lastFilterSelected)
  807. switch index {
  808. case 0:
  809. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.bestCards)
  810. case 1:
  811. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.cashBack)
  812. case 2:
  813. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.noAnnualFee)
  814. case 3:
  815. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.introPurchaseAPR)
  816. case 4:
  817. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.rewards)
  818. case 5:
  819. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.balanceTransfer)
  820. default:
  821. print("")
  822. }
  823. }
  824.  
  825. }
  826.  
  827. struct FilterData {
  828.  
  829. var title = ""
  830. var imageName = ""
  831.  
  832. init(title: String, imageName: String) {
  833. self.title = title
  834. self.imageName = imageName
  835. }
  836.  
  837. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement