Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.88 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.  
  441. func numberOfSections(in tableView: UITableView) -> Int {
  442. return 1
  443. }
  444.  
  445. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  446. switch currentTab {
  447. case .creditCards:
  448. let cards = creditCardSections[section]
  449. return min(3, cards.count)
  450. case .personalLoans:
  451. return 1
  452. }
  453. }
  454.  
  455. func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  456. switch currentTab {
  457. case .creditCards:
  458. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ccHeaderIdentifier)
  459. let backgroundView = view?.viewWithTag(10)
  460. let label = view?.labelWithTag(11)
  461.  
  462. backgroundView?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  463.  
  464. label?.font = UIFont.latoBlack(20)
  465. label?.textColor = UIColor.creditSesameDarkTextColor
  466.  
  467. let attributedText = NSMutableAttributedString(string: NSLocalizedString("Best Cards", comment: "Best Cards Cards Header"), attributes:
  468. [NSAttributedString.Key.foregroundColor : UIColor.init(rgb: 0x929292),
  469. NSAttributedString.Key.font : UIFont.lato(20)])
  470. attributedText.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.creditSesameGrayTextColor,
  471. NSAttributedString.Key.font : UIFont.latoHeavy(20)], range: (attributedText.string as NSString).range(of: "Best Cards"))
  472. label?.attributedText = attributedText
  473. view?.addTopSeparator()
  474. if TestingManager.shared.newCCFilteringVariation == Variations.control {
  475. return nil
  476. } else {
  477. return view
  478. }
  479.  
  480. case .personalLoans:
  481. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: pLHeaderIdentifier)
  482. let amountLabel = view?.labelWithTag(21)
  483. let amountView = view?.viewWithTag(200)
  484. let amountTextField = view?.textFieldWithTag(22) as? TextField
  485. let amountTooltip = view?.buttonWithTag(23)
  486. let incomeLabel = view?.labelWithTag(31)
  487. let incomeView = view?.viewWithTag(300)
  488. let incomeTextField = view?.textFieldWithTag(32) as? TextField
  489. let incomeTooltip = view?.buttonWithTag(33)
  490.  
  491. let amountNumber = loanAmountTextField?.text?.removeMoneyFormat() ?? NSNumber(value: loanAmount)
  492. let annualIncome = annualIncomeTextField?.text?.removeMoneyFormat() ?? CreditSesameRestClient.shared.user?.annualIncome ?? NSNumber(value: 0)
  493.  
  494. amountLabel?.font = UIFont.lato(16)
  495. amountLabel?.textColor = UIColor.creditSesameGrayTextColor
  496. amountLabel?.text = NSLocalizedString("Loan Amount", comment: "loan amount label")
  497. amountTextField?.text = String.moneyFormattedString(number: amountNumber)
  498. amountTextField?.font = UIFont.latoMedium(16)
  499. amountTextField?.textColor = UIColor.black
  500. amountTextField?.keyboardType = .numberPad
  501. amountTextField?.delegate = self
  502. amountTextField?.maxCharacters = 6
  503. amountView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor
  504. amountView?.layer.borderWidth = 1
  505. loanAmountTextField = amountTextField
  506. amountTooltip?.addTarget(self, action: #selector(showPLAmountTooltip), for: .touchUpInside)
  507.  
  508. amountView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editAmount)))
  509.  
  510. incomeLabel?.font = UIFont.lato(16)
  511. incomeLabel?.textColor = UIColor.creditSesameGrayTextColor
  512. incomeLabel?.text = NSLocalizedString("Annual Income", comment: "income label")
  513. incomeTextField?.text = String.moneyFormattedString(number: annualIncome)
  514. incomeTextField?.font = UIFont.latoMedium(16)
  515. incomeTextField?.textColor = UIColor.black
  516. incomeTextField?.keyboardType = .numberPad
  517. incomeTextField?.delegate = self
  518. incomeTextField?.maxCharacters = 7
  519. incomeView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor
  520. incomeView?.layer.borderWidth = 1
  521. annualIncomeTextField = incomeTextField
  522. incomeTooltip?.addTarget(self, action: #selector(showPLIncomeTooltip), for: .touchUpInside)
  523.  
  524. incomeView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editIncome)))
  525.  
  526. return view
  527. }
  528.  
  529. }
  530.  
  531. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
  532. return currentTab == .creditCards ? (TestingManager.shared.newCCFilteringVariation == Variations.variation ? 72 : 36) : 60
  533. }
  534.  
  535. func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  536. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerIdentifier)
  537. let actionView = view?.viewWithTag(100)
  538. let button = view?.buttonWithTag(10)
  539. let line = view?.viewWithTag(11)
  540. line?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  541. button?.setTitleColor(UIColor.creditSesameCyan, for: .normal)
  542. button?.titleLabel?.font = UIFont.lato(14)
  543. view?.backgroundColor = UIColor.white
  544. actionView?.addTopSeparator()
  545. actionView?.addBottomSeparator()
  546.  
  547. switch currentTab {
  548. case .creditCards:
  549.  
  550. if TestingManager.shared.newCCFilteringVariation == Variations.variation {
  551. return newMoreFooterView
  552. }
  553. button?.setTitle(NSLocalizedString("See All Credit Cards", comment: "More Cards button"), for: .normal)
  554. button?.superview?.tag = section
  555. button?.removeTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside)
  556. button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  557.  
  558. case .personalLoans:
  559. guard let _ = personalLoan else {
  560. return nil
  561. }
  562. button?.setTitle(NSLocalizedString("See More Personal Loans", comment: "More Cards button"), for: .normal)
  563. button?.removeTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  564. button?.addTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside)
  565.  
  566. }
  567.  
  568. return view
  569.  
  570. }
  571.  
  572. var newMoreFooterView: UIView? {
  573. let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: newMoreCardsButton)
  574. let button = view?.buttonWithTag(10)
  575. button?.setTitleColor(UIColor.white, for: .normal)
  576. button?.titleLabel?.font = UIFont.latoSemiBold(13)
  577. button?.backgroundColor = UIColor.creditSesameCyan
  578. button?.setTitle(NSLocalizedString("Search All Credit Cards", comment: "More Cards"), for: .normal)
  579. view?.addTopSeparator()
  580. button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside)
  581. return view
  582. }
  583.  
  584. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  585. switch currentTab {
  586. case .creditCards:
  587. let creditCards = creditCardSections[indexPath.section]
  588. let creditCard = creditCards[indexPath.row]
  589. var creditCardCell: ClickApplyCell? = nil
  590. var pagePosition: String
  591.  
  592. pagePosition = AnalyticsPagePosition.bestCards
  593. creditCardCell = cellForCreditCard(creditCard: creditCard, offerType: .estimatedCreditLimit)
  594. creditCardCell?.contentView.tag = indexPath.row
  595.  
  596. let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1
  597. creditCardCell?.cellPosition = "\(offerPosition)"
  598. creditCardCell?.pagePosition = pagePosition
  599. creditCardCell?.offer = creditCard
  600. creditCardCell?.selectionStyle = .none
  601. creditCardCell?.addTopSeparator()
  602.  
  603. trackViewOfferCreditCard(creditCard: creditCard, pagePosition: pagePosition, pageLocation: nil, offerPosition: creditCardCell?.cellPosition!)
  604. return creditCardCell!
  605.  
  606. case .personalLoans:
  607. if let loan = personalLoan {
  608. let personalLoanCell = cellForPersonalLoan(pL: loan, offerType: loan.offerType)
  609. let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1
  610. personalLoanCell.cellPosition = "\(offerPosition)"
  611. personalLoanCell.pagePosition = nil
  612. personalLoanCell.pageLocation = nil
  613. personalLoanCell.offer = loan
  614. personalLoanCell.selectionStyle = .none
  615.  
  616. trackViewOfferPersonalLoan(personalLoan: personalLoan!, pagePosition: nil, pageLocation: nil, offerPosition: "1")
  617. return personalLoanCell
  618. }
  619. else if let cell = tableView.dequeueReusableCell(withIdentifier: notFoundIdentifier) {
  620.  
  621. for v in cell.contentView.subviews {
  622. v.removeFromSuperview()
  623. }
  624.  
  625. let view = UIView.loadNib("OffersNotFoundView")
  626. let titleLabel = view.labelWithTag(10)
  627. let contentLabel = view.labelWithTag(11)
  628. let actionView = view.viewWithTag(20)
  629. let actionButton = view.buttonWithTag(21)
  630. let accessibilityView = view.viewWithTag(30)!
  631.  
  632. titleLabel?.font = UIFont.latoHeavy(18)
  633. titleLabel?.textColor = UIColor.init(rgb: 0x606060)
  634. titleLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundTitle ?? NSLocalizedString("Loans Offer Not Found title", comment: "Not found title")
  635. contentLabel?.font = UIFont.lato(14)
  636. contentLabel?.textColor = UIColor.init(rgb: 0x606060)
  637. contentLabel?.textAlignment = .left
  638. contentLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundContent ?? NSLocalizedString("Loans Offer Not Found content", comment: "Not found content")
  639. contentLabel?.numberOfLines = 0
  640. contentLabel?.lineBreakMode = .byWordWrapping
  641.  
  642. actionView?.isHidden = false
  643. let buttonTitle = currentTab == .creditCards ? NSLocalizedString("Search All Credit Cards", comment: "Market place button") : NSLocalizedString("Search All Personal Loans", comment: "Market place button")
  644. actionButton?.setThemeInfoButton(title: buttonTitle)
  645. let selector = currentTab == .creditCards ? #selector(openCreditCardsMarketplace) : #selector(openPersonalLoansMarketplace)
  646. actionButton?.addTarget(self, action: selector, for: .touchUpInside)
  647.  
  648. cell.contentView.addSubview(view)
  649. view.snp.makeConstraints({ make in
  650. make.edges.equalToSuperview()
  651. })
  652.  
  653. cell.selectionStyle = .none
  654. cell.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor
  655.  
  656. accessibilityView.isAccessibilityElement = true
  657. accessibilityView.accessibilityLabel = "\(titleLabel?.text ?? ""): \(contentLabel?.text ?? "")"
  658.  
  659. return cell
  660. }
  661. }
  662.  
  663. return UITableViewCell()
  664. }
  665.  
  666. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  667. tableView.deselectRow(at: indexPath, animated: true)
  668. }
  669.  
  670. }
  671.  
  672. extension BestOffersViewController: UITextFieldDelegate {
  673.  
  674. func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
  675. textField.text = "\(textField.text?.removeMoneyFormat().intValue ?? 0)"
  676.  
  677. if textField == self.loanAmountTextField {
  678. trackClick(clickType: AnalyticsClickType.enterLoanAmount, pagePosition: nil)
  679. }
  680.  
  681. // update annual income
  682. if textField == self.annualIncomeTextField {
  683. trackClick(clickType: AnalyticsClickType.updateIncome, pagePosition: nil)
  684. }
  685.  
  686. return true
  687. }
  688.  
  689. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  690.  
  691. let currentString = textField.text! as NSString
  692. let newString = currentString.replacingCharacters(in: range, with: string) as NSString
  693.  
  694. if let textField = textField as? TextField, let maxLength = textField.maxCharacters, newString.length > maxLength {
  695. return false
  696. }
  697.  
  698. if let timer = timer {
  699. timer.startTimer()
  700. }
  701. else {
  702. timer = CSTimer()
  703. timer?.action = {
  704.  
  705. if (self.annualIncomeTextField?.text?.count ?? 0) == 0 || (self.loanAmountTextField?.text?.count ?? 0) == 0 {
  706. return
  707. }
  708.  
  709. self.loadPersonalLoanIfNeeded(isInputChange: true)
  710. DispatchQueue.main.async {
  711. self.hideKeyboard()
  712. }
  713. }
  714. timer?.startTimer()
  715. }
  716. return true
  717. }
  718.  
  719. func textFieldDidEndEditing(_ textField: UITextField) {
  720. let money = textField.text?.removeMoneyFormat().doubleValue ?? 0
  721.  
  722. // update amount needed
  723. if textField == self.loanAmountTextField {
  724. guard money >= 0 && money <= 100000 else {
  725. let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorLoanAmount ?? NSLocalizedString("AmountNeededTooltip", comment: "amount loan error")
  726. showAppClientError(message)
  727. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  728. amountInputError = true
  729. return
  730. }
  731. amountInputError = false
  732. loanAmount = Int(money)
  733. }
  734.  
  735. // update annual income
  736. if textField == self.annualIncomeTextField {
  737. guard money > 0 else {
  738. let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorAnnualIncome ?? NSLocalizedString("CalculateDTIIncomeError", comment: "invalid income error")
  739. showAppClientError(message)
  740. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  741. incomeInputError = true
  742. return
  743. }
  744.  
  745. incomeInputError = false
  746. let user = CreditSesameRestClient.shared.user?.copy() as? User ?? User()
  747. if user.annualIncome?.doubleValue != money {
  748. user.annualIncome = NSNumber(value: money)
  749. CreditSesameRestClient.shared.updateUser(user: user, password: AppContext.shared.password)
  750. }
  751. }
  752.  
  753. textField.text = String.moneyFormattedString(number: NSNumber(value: money))
  754. }
  755. }
  756.  
  757. extension BestOffersViewController: DGScrollableSegmentControlDataSource,DGScrollableSegmentControlDelegate {
  758.  
  759.  
  760. func numbersOfItem() -> Int {
  761. return filters.count
  762. }
  763.  
  764. func itemfor(_ index: Int) -> DGItem {
  765.  
  766. let item = DGItem()
  767. item.setTitle(filters[index].title, for: .normal)
  768. item.isSelected = index == lastFilterSelected
  769. item.setImage(UIImage(named: filters[index].imageName), for: .normal)
  770. item.titleLabel?.font = UIFont.latoSemiBold(12)
  771.  
  772. if item.isSelected {
  773. item.setTitleColor(UIColor.white, for: .normal)
  774. item.backgroundColor = UIColor.creditSesameCyan
  775. } else {
  776. item.setTitleColor(UIColor.creditSesameCyan, for: .normal)
  777. item.backgroundColor = UIColor.white
  778. }
  779.  
  780. return item
  781.  
  782. }
  783.  
  784. func didSelect(_ item: DGItem, atIndex index: Int) {
  785. lastFilterSelected = index
  786. loadData(index: lastFilterSelected)
  787. switch index {
  788. case 0:
  789. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.bestCards)
  790. case 1:
  791. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.cashBack)
  792. case 2:
  793. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.noAnnualFee)
  794. case 3:
  795. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.introPurchaseAPR)
  796. case 4:
  797. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.rewards)
  798. case 5:
  799. trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.balanceTransfer)
  800. default:
  801. print("")
  802. }
  803. }
  804.  
  805. }
  806.  
  807. struct FilterData {
  808.  
  809. var title = ""
  810. var imageName = ""
  811.  
  812. init(title: String, imageName: String) {
  813. self.title = title
  814. self.imageName = imageName
  815. }
  816.  
  817. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement