Created
June 6, 2019 19:17
-
-
Save FabiolaRamirez/de17d2b3481e90634fd2a5fead3d8638 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// BestOffersViewController.swift | |
// finance | |
// | |
// Created by David Yanez on 4/2/18. | |
// Copyright © 2018 creditsesame. All rights reserved. | |
// | |
import UIKit | |
import SnapKit | |
enum OffersTab: String { | |
case creditCards = "CCs" | |
case personalLoans = "PLs" | |
} | |
enum FilterCategory: Int { | |
case bestCards | |
case cashBack | |
case noAnnualFee | |
case introPurchaseAPR | |
case rewards | |
case balanceTransfer | |
var pagePosition: String { | |
switch self { | |
case .bestCards: | |
return AnalyticsPagePosition.bestCards | |
case .cashBack: | |
return AnalyticsPagePosition.cashBack | |
case .noAnnualFee: | |
return AnalyticsPagePosition.noAnnualFee | |
case .introPurchaseAPR: | |
return AnalyticsPagePosition.introPurchaseAPR | |
case .rewards: | |
return AnalyticsPagePosition.rewards | |
case .balanceTransfer: | |
return AnalyticsPagePosition.balanceTransfer | |
} | |
} | |
} | |
class BestOffersViewController: OffersViewController, UITableViewDelegate, UITableViewDataSource { | |
let ccHeaderIdentifier = "BestCardsHeaderView" | |
let notFoundIdentifier = "notFoundCellIdentifier" | |
let pLHeaderIdentifier = "BestPersonalLoanHeaderView" | |
let footerIdentifier = "MoreCardsFooter" | |
let newMoreCardsButton = "NewMoreCardsButton" | |
let dismissViewTag = 989898 | |
var bestCards: [CreditCard]? | |
var creditCardSections: [[CreditCard]] = [] | |
var personalLoan: PersonalLoan? | |
var offersHeaderView: UIView! | |
var currentTab: OffersTab = .creditCards | |
var previousPLCallWasEmptyNoErrors = false | |
var inputError: Bool { | |
return incomeInputError || amountInputError | |
} | |
var incomeInputError = false | |
var amountInputError = false | |
var loanAmount: Int { | |
get { | |
return AppContext.shared.pLAmountNeeded | |
} | |
set { | |
AppContext.shared.pLAmountNeeded = newValue | |
} | |
} | |
var loanAmountTextField: UITextField? | |
var annualIncomeTextField: UITextField? | |
var timer: CSTimer? | |
override var screeName: String { | |
get { | |
return currentTab == .creditCards ? AnalyticsScreenName.ccOffers : AnalyticsScreenName.plOffers | |
} | |
} | |
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") | |
] | |
var lastFilterSelected: Int { | |
get { | |
return UserDefaults.standard.integer(forKey: "lastFilterSelected") | |
} | |
set { | |
UserDefaults.standard.set(newValue, forKey: "lastFilterSelected") | |
UserDefaults.standard.synchronize() | |
} | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
edgesForExtendedLayout = [] | |
tableView.register(UINib(nibName: ccHeaderIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: ccHeaderIdentifier) | |
tableView.register(UINib(nibName: pLHeaderIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: pLHeaderIdentifier) | |
tableView.register(UINib(nibName: footerIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: footerIdentifier) | |
tableView.register(UINib(nibName: newMoreCardsButton, bundle: nil), forHeaderFooterViewReuseIdentifier: newMoreCardsButton) | |
tableView.register(UITableViewCell.self, forCellReuseIdentifier: notFoundIdentifier) | |
tableView.estimatedRowHeight = 300 | |
tableView.rowHeight = UITableView.automaticDimension | |
tableView.estimatedSectionHeaderHeight = 300 | |
tableView.sectionHeaderHeight = UITableView.automaticDimension | |
tableView.estimatedSectionFooterHeight = 36 | |
tableView.separatorStyle = .singleLine | |
tableView.separatorColor = .white | |
tableView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
configureStatusBar(color: UIColor.white) | |
if CreditSesameRestClient.shared.canShowCreditCardsFilter, TestingManager.shared.newCCFilteringVariation == Variations.variation { | |
loadData(index: FilterCategory(rawValue: lastFilterSelected) ?? .bestCards) | |
} else { | |
loadData(index: .bestCards) | |
configureFooter() | |
} | |
configureHeader() | |
} | |
override func scrollToTop() { | |
tableView?.setContentOffset(.zero, animated: true) | |
} | |
func configureHeader() { | |
offersHeaderView = UIView.loadNib("OffersHeaderView") | |
offersHeaderView.backgroundColor = UIColor.white | |
let titleLabel = offersHeaderView.labelWithTag(20) | |
let descriptionLabel = offersHeaderView.labelWithTag(21) | |
let ccButton = offersHeaderView.buttonWithTag(31) | |
let pLButton = offersHeaderView.buttonWithTag(41) | |
titleLabel?.font = UIFont.latoHeavy(20) | |
titleLabel?.textColor = UIColor.creditSesameGrayTextColor | |
titleLabel?.text = NSLocalizedString("Your Borrowing Power", comment: "Your Borrowing Power") | |
let textDescription = NSLocalizedString("CreditCardBorrowingPowerDescription", comment: "card borrowing description") | |
let boldText = NSLocalizedString("credit profile", comment: "credit profile text") | |
let attributedDescription = NSMutableAttributedString(string: textDescription, attributes: [NSAttributedString.Key.font : UIFont.lato(16), NSAttributedString.Key.foregroundColor : UIColor.creditSesameDarkTextColor]) | |
attributedDescription.addAttributes([NSAttributedString.Key.font : UIFont.latoBold(16)], range: (textDescription as NSString).range(of: boldText)) | |
descriptionLabel?.attributedText = attributedDescription | |
descriptionLabel?.numberOfLines = 0 | |
descriptionLabel?.lineBreakMode = .byWordWrapping | |
let height = offersHeaderView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height | |
let headerView = UITableViewHeaderFooterView(frame: CGRect(x: 0, y: 0, width: 0, height: height)) | |
headerView.backgroundColor = UIColor.clear | |
headerView.addSubview(offersHeaderView) | |
offersHeaderView.clipsToBounds = true | |
offersHeaderView.snp.makeConstraints { (make) in | |
make.edges.equalToSuperview() | |
} | |
let selectedttributtes = [NSAttributedString.Key.font : UIFont.lato(16), | |
NSAttributedString.Key.foregroundColor : UIColor.creditSesameCyan, | |
NSAttributedString.Key.kern : 0.5] as [NSAttributedString.Key : Any] | |
let unselectedAttributtes = [NSAttributedString.Key.font : UIFont.lato(16), | |
NSAttributedString.Key.foregroundColor : UIColor.init(rgb: 0x757575), | |
NSAttributedString.Key.kern : 0.5] as [NSAttributedString.Key : Any] | |
let creditTitle = NSAttributedString(string: NSLocalizedString("Credit Cards", comment: "credit cards button"), attributes: selectedttributtes) | |
let creditTitleUnSelected = NSAttributedString(string: creditTitle.string, attributes: unselectedAttributtes) | |
ccButton?.setAttributedTitle(creditTitle, for: .selected) | |
ccButton?.setAttributedTitle(creditTitleUnSelected, for: .normal) | |
ccButton?.isSelected = true | |
ccButton?.addTarget(self, action: #selector(switchToCards), for: .touchUpInside) | |
let debtTitle = NSAttributedString(string: NSLocalizedString("Personal Loans", comment: "personal loans button"), attributes: selectedttributtes) | |
let debtTitleUnSelected = NSAttributedString(string: debtTitle.string, attributes: unselectedAttributtes) | |
pLButton?.setAttributedTitle(debtTitleUnSelected, for: .normal) | |
pLButton?.setAttributedTitle(debtTitle, for: .selected) | |
pLButton?.backgroundColor = UIColor.clear | |
pLButton?.isSelected = false | |
pLButton?.addTarget(self, action: #selector(switchToPLs), for: .touchUpInside) | |
let button = offersHeaderView.buttonWithTag(10) | |
button?.setThemeAdvertiserDisclosure() | |
button?.backgroundColor = UIColor.clear | |
button?.addTarget(self, action: #selector(showAdvertisersDisclosureTooltip), for: .touchUpInside) | |
tableView.tableHeaderView = headerView | |
addOrRemoveSegmentFilter() | |
} | |
func disclosureFooterView() -> DisclosureFooterView { | |
let disclosureFooterView = DisclosureFooterView() | |
disclosureFooterView.providerTermsPressed = { [weak self] in | |
self?.showProviderTermsDisclosureTooltip() | |
} | |
disclosureFooterView.editorialDisclosurePressed = { [weak self] in | |
self?.showEditorialDisclosureTooltip() | |
} | |
return disclosureFooterView | |
} | |
func configureFooter() { | |
if currentTab == .personalLoans || (CreditSesameRestClient.shared.canShowCreditCardsFilter && TestingManager.shared.newCCFilteringVariation == Variations.variation) { | |
tableView.tableFooterView = nil | |
return | |
} | |
let offersFooterView = UIView.loadNib("OffersFooterView") | |
offersFooterView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
let balanceButton = offersFooterView.buttonWithTag(11)! | |
balanceButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside) | |
balanceButton.accessibilityLabel = NSLocalizedString("Balance Transfer", comment: "BT Cards Header") | |
let zeroPercentButton = offersFooterView.buttonWithTag(12)! | |
zeroPercentButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside) | |
zeroPercentButton.accessibilityLabel = NSLocalizedString("ZeroPurchaseAPR", comment: "0% Intro Purchase APR Header") | |
let rewardsButton = offersFooterView.buttonWithTag(13)! | |
rewardsButton.addTarget(self, action: #selector(browseCategories(button:)), for: .touchUpInside) | |
rewardsButton.accessibilityLabel = NSLocalizedString("Rewards", comment: "Rewards Cards Header") | |
let titleLabel = offersFooterView.labelWithTag(10) | |
titleLabel?.font = UIFont.latoBold(20) | |
titleLabel?.textColor = UIColor.creditSesameDarkTextColor | |
titleLabel?.text = NSLocalizedString("Credit Card Categories", comment: "Footer categories") | |
let height = offersFooterView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height | |
let footerView = UITableViewHeaderFooterView(frame: CGRect(x: 0, y: 0, width: 0, height: height)) | |
footerView.backgroundColor = UIColor.clear | |
footerView.addSubview(offersFooterView) | |
offersFooterView.clipsToBounds = true | |
offersFooterView.snp.makeConstraints { (make) in | |
make.edges.equalToSuperview() | |
} | |
let disclosureContainerView = offersFooterView.viewWithTag(14) | |
let disclosureView = disclosureFooterView() | |
disclosureContainerView?.addSubview(disclosureView) | |
disclosureView.snp.makeConstraints { make in | |
make.edges.equalToSuperview() | |
} | |
tableView.tableFooterView = footerView | |
} | |
func loadPersonalLoanIfNeeded(isInputChange: Bool = false) { | |
let currentIncome = CreditSesameRestClient.shared.user?.annualIncome | |
let currentAmount = AppContext.shared.pLAmountNeeded | |
// update income and amount if they did change | |
var needsNewPLFromServer = false | |
if let income = annualIncomeTextField?.text?.removeMoneyFormat() { | |
if let userIncome = currentIncome, income.doubleValue != userIncome.doubleValue { | |
let newIncome = isInputChange ? income : userIncome | |
annualIncomeTextField?.text = String.moneyFormattedString(number: newIncome) | |
incomeInputError = false | |
needsNewPLFromServer = true | |
} | |
} | |
if let amount = loanAmountTextField?.text?.removeMoneyFormat() { | |
if amount.intValue != currentAmount { | |
let newAmount = isInputChange ? amount : NSNumber(value: currentAmount) | |
loanAmountTextField?.text = String.moneyFormattedString(number: newAmount) | |
amountInputError = false | |
needsNewPLFromServer = true | |
} | |
} | |
if (personalLoan != nil || (personalLoan == nil && previousPLCallWasEmptyNoErrors && !inputError)) && !needsNewPLFromServer { | |
self.tableView.reloadData() | |
self.configureFooter() | |
self.addOrRemoveSegmentFilter() | |
return | |
} | |
let annualIncome = annualIncomeTextField?.text?.removeMoneyFormat().intValue ?? CreditSesameRestClient.shared.user?.annualIncome?.intValue ?? 0 | |
let amount = loanAmountTextField?.text?.removeMoneyFormat().intValue ?? loanAmount | |
showProgressView() | |
CreditSesameRestClient.shared.getAllPersonalLoans(loanAmount: amount, annualIncome: annualIncome, page: 1, itemsPerPage: 10) { (personalLoans, error) in | |
self.hideProgressView() | |
if let _ = error { | |
self.personalLoan = nil | |
self.previousPLCallWasEmptyNoErrors = false | |
} | |
else if let personalLoans = personalLoans, personalLoans.count > 0 { | |
self.personalLoan = personalLoans.first | |
self.previousPLCallWasEmptyNoErrors = false | |
} | |
else { | |
self.personalLoan = nil | |
self.previousPLCallWasEmptyNoErrors = true | |
} | |
self.tableView.reloadData() | |
self.configureFooter() | |
self.addOrRemoveSegmentFilter() | |
} | |
} | |
override func keyboardWillShow(_ notification: Notification) { | |
super.keyboardWillShow(notification) | |
if view.viewWithTag(dismissViewTag) == nil { | |
let dismissView = UIView() | |
let dismissTapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView(_:))) | |
dismissView.tag = dismissViewTag | |
dismissView.backgroundColor = UIColor.clear | |
dismissView.addGestureRecognizer(dismissTapGesture) | |
view.addSubview(dismissView) | |
dismissView.snp.makeConstraints { make in | |
make.edges.equalToSuperview() | |
} | |
} | |
} | |
override func keyboardWillHide(_ notification: Notification) { | |
super.keyboardWillHide(notification) | |
if let v = view.viewWithTag(dismissViewTag) { | |
v.removeFromSuperview() | |
} | |
} | |
@objc func switchToCards() { | |
if currentTab == .creditCards { | |
return | |
} | |
let ccButton = offersHeaderView.buttonWithTag(31) | |
let ccBorderView = offersHeaderView.viewWithTag(32) | |
let pLButton = offersHeaderView.buttonWithTag(41) | |
let pLBorderView = offersHeaderView.viewWithTag(42) | |
ccButton?.isSelected = true | |
ccBorderView?.isHidden = false | |
pLButton?.isSelected = false | |
pLBorderView?.isHidden = true | |
currentTab = .creditCards | |
addOrRemoveSegmentFilter() | |
tableView.reloadData() | |
configureFooter() | |
trackViewPage() | |
} | |
@objc func switchToPLs() { | |
if currentTab == .personalLoans { | |
return | |
} | |
let ccButton = offersHeaderView.buttonWithTag(31) | |
let ccBorderView = offersHeaderView.viewWithTag(32) | |
let pLButton = offersHeaderView.buttonWithTag(41) | |
let pLBorderView = offersHeaderView.viewWithTag(42) | |
ccButton?.isSelected = false | |
ccBorderView?.isHidden = true | |
pLButton?.isSelected = true | |
pLBorderView?.isHidden = false | |
currentTab = .personalLoans | |
loadPersonalLoanIfNeeded() | |
trackViewPage() | |
} | |
@objc func browseCategories(button: UIButton) { | |
switch button.tag { | |
case 11: | |
let cards = CreditSesameRestClient.shared.balanceTransferCards ?? [] | |
self.openCreditCards(screen: .bestCardsBT, creditCards: cards) | |
trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsBT) | |
case 12: | |
let cards = CreditSesameRestClient.shared.zeroPercentCards ?? [] | |
self.openCreditCards(screen: .bestCardsZeroPercent, creditCards: cards) | |
trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsZeroPercent) | |
case 13: | |
let cards = CreditSesameRestClient.shared.rewardsCards ?? [] | |
self.openCreditCards(screen: .bestCardsRewards, creditCards: cards) | |
trackClickNavigation(navigationLocation: AnalyticsNavLocation.bestCardsRewards) | |
default: | |
break | |
} | |
} | |
@objc func viewMoreCards(button: UIButton) { | |
openCreditCardsMarketplace() | |
} | |
@objc func editAmount() { | |
loanAmountTextField?.becomeFirstResponder() | |
} | |
@objc func editIncome() { | |
annualIncomeTextField?.becomeFirstResponder() | |
} | |
override func viewWillAppear(_ animated: Bool) { | |
super.viewWillAppear(animated) | |
navigationController?.setNavigationBarHidden(true, animated: true) | |
creditSesameNavigationController?.setNavigationBarHidden(true, animated: true) | |
} | |
override func viewDidAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
if currentTab == .personalLoans { | |
self.loadPersonalLoanIfNeeded() | |
} | |
} | |
func loadData(index: FilterCategory) { | |
switch index { | |
case .bestCards: | |
creditCardSections = [CreditSesameRestClient.shared.bestCards ?? []] | |
case .cashBack: | |
creditCardSections = [CreditSesameRestClient.shared.cashBackCards ?? []] | |
case .noAnnualFee: | |
creditCardSections = [CreditSesameRestClient.shared.noAnnualFeeCards ?? []] | |
case .introPurchaseAPR: | |
creditCardSections = [CreditSesameRestClient.shared.zeroPercentCards ?? []] | |
case .rewards: | |
creditCardSections = [CreditSesameRestClient.shared.rewardsCards ?? []] | |
case .balanceTransfer: | |
creditCardSections = [CreditSesameRestClient.shared.balanceTransferCards ?? []] | |
} | |
self.tableView.reloadData() | |
} | |
func addOrRemoveSegmentFilter() { | |
let spaceFilterView: UIView = offersHeaderView.viewWithTag(49)! | |
let segmentControl = offersHeaderView.viewWithTag(43) as! DGScrollableSegmentControl | |
spaceFilterView.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
segmentControl.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
segmentControl.delegate = self | |
segmentControl.datasource = self | |
segmentControl.updateHeightConstraint(height: 0, constraintIdentifier: "filterHeight") | |
spaceFilterView.updateHeightConstraint(height: 0, constraintIdentifier: "heightSpaceFilter") | |
if CreditSesameRestClient.shared.canShowCreditCardsFilter, TestingManager.shared.newCCFilteringVariation == Variations.variation, currentTab == .creditCards { | |
segmentControl.updateHeightConstraint(height: 32, constraintIdentifier: "filterHeight") | |
spaceFilterView.updateHeightConstraint(height: 16, constraintIdentifier: "heightSpaceFilter") | |
} | |
sizeHeaderToFit() | |
} | |
func sizeHeaderToFit() { | |
if let headerView = tableView.tableHeaderView { | |
headerView.setNeedsLayout() | |
headerView.layoutIfNeeded() | |
let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height | |
var frame = headerView.frame | |
frame.size.height = height | |
headerView.frame = frame | |
tableView.tableHeaderView = headerView | |
} | |
} | |
func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
switch currentTab { | |
case .creditCards: | |
let cards = creditCardSections[section] | |
return min(3, cards.count) | |
case .personalLoans: | |
return 1 | |
} | |
} | |
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { | |
switch currentTab { | |
case .creditCards: | |
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ccHeaderIdentifier) | |
let backgroundView = view?.viewWithTag(10) | |
let label = view?.labelWithTag(11) | |
backgroundView?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
label?.font = UIFont.latoBlack(20) | |
label?.textColor = UIColor.creditSesameDarkTextColor | |
let attributedText = NSMutableAttributedString(string: NSLocalizedString("Best Cards", comment: "Best Cards Cards Header"), attributes: | |
[NSAttributedString.Key.foregroundColor : UIColor.init(rgb: 0x929292), | |
NSAttributedString.Key.font : UIFont.lato(20)]) | |
attributedText.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.creditSesameGrayTextColor, | |
NSAttributedString.Key.font : UIFont.latoHeavy(20)], range: (attributedText.string as NSString).range(of: "Best Cards")) | |
label?.attributedText = attributedText | |
view?.addTopSeparator() | |
if CreditSesameRestClient.shared.canShowCreditCardsFilter, TestingManager.shared.newCCFilteringVariation == Variations.variation { | |
return nil | |
} else { | |
return view | |
} | |
case .personalLoans: | |
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: pLHeaderIdentifier) | |
let amountLabel = view?.labelWithTag(21) | |
let amountView = view?.viewWithTag(200) | |
let amountTextField = view?.textFieldWithTag(22) as? TextField | |
let amountTooltip = view?.buttonWithTag(23) | |
let incomeLabel = view?.labelWithTag(31) | |
let incomeView = view?.viewWithTag(300) | |
let incomeTextField = view?.textFieldWithTag(32) as? TextField | |
let incomeTooltip = view?.buttonWithTag(33) | |
let amountNumber = loanAmountTextField?.text?.removeMoneyFormat() ?? NSNumber(value: loanAmount) | |
let annualIncome = annualIncomeTextField?.text?.removeMoneyFormat() ?? CreditSesameRestClient.shared.user?.annualIncome ?? NSNumber(value: 0) | |
amountLabel?.font = UIFont.lato(16) | |
amountLabel?.textColor = UIColor.creditSesameGrayTextColor | |
amountLabel?.text = NSLocalizedString("Loan Amount", comment: "loan amount label") | |
amountTextField?.text = String.moneyFormattedString(number: amountNumber) | |
amountTextField?.font = UIFont.latoMedium(16) | |
amountTextField?.textColor = UIColor.black | |
amountTextField?.keyboardType = .numberPad | |
amountTextField?.delegate = self | |
amountTextField?.maxCharacters = 6 | |
amountView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor | |
amountView?.layer.borderWidth = 1 | |
loanAmountTextField = amountTextField | |
amountTooltip?.addTarget(self, action: #selector(showPLAmountTooltip), for: .touchUpInside) | |
amountView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editAmount))) | |
incomeLabel?.font = UIFont.lato(16) | |
incomeLabel?.textColor = UIColor.creditSesameGrayTextColor | |
incomeLabel?.text = NSLocalizedString("Annual Income", comment: "income label") | |
incomeTextField?.text = String.moneyFormattedString(number: annualIncome) | |
incomeTextField?.font = UIFont.latoMedium(16) | |
incomeTextField?.textColor = UIColor.black | |
incomeTextField?.keyboardType = .numberPad | |
incomeTextField?.delegate = self | |
incomeTextField?.maxCharacters = 7 | |
incomeView?.layer.borderColor = UIColor.creditSesameGrayBackgroundColor.cgColor | |
incomeView?.layer.borderWidth = 1 | |
annualIncomeTextField = incomeTextField | |
incomeTooltip?.addTarget(self, action: #selector(showPLIncomeTooltip), for: .touchUpInside) | |
incomeView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(editIncome))) | |
return view | |
} | |
} | |
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { | |
return currentTab == .creditCards ? (CreditSesameRestClient.shared.canShowCreditCardsFilter && TestingManager.shared.newCCFilteringVariation == Variations.variation ? 72 : 36) : 60 | |
} | |
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { | |
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerIdentifier) | |
let actionView = view?.viewWithTag(100) | |
let button = view?.buttonWithTag(10) | |
let line = view?.viewWithTag(11) | |
line?.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
button?.setTitleColor(UIColor.creditSesameCyan, for: .normal) | |
button?.titleLabel?.font = UIFont.lato(14) | |
view?.backgroundColor = UIColor.white | |
actionView?.addTopSeparator() | |
actionView?.addBottomSeparator() | |
switch currentTab { | |
case .creditCards: | |
if CreditSesameRestClient.shared.canShowCreditCardsFilter, TestingManager.shared.newCCFilteringVariation == Variations.variation { | |
return newMoreFooterView | |
} | |
button?.setTitle(NSLocalizedString("See All Credit Cards", comment: "More Cards button"), for: .normal) | |
button?.superview?.tag = section | |
button?.removeTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside) | |
button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside) | |
case .personalLoans: | |
guard let _ = personalLoan else { | |
return nil | |
} | |
button?.setTitle(NSLocalizedString("See More Personal Loans", comment: "More Cards button"), for: .normal) | |
button?.removeTarget(self, action: #selector(viewMoreCards), for: .touchUpInside) | |
button?.addTarget(self, action: #selector(openPersonalLoansMarketplace), for: .touchUpInside) | |
} | |
return view | |
} | |
var newMoreFooterView: UIView? { | |
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: newMoreCardsButton) | |
let button = view?.buttonWithTag(10) | |
button?.setTitleColor(UIColor.white, for: .normal) | |
button?.titleLabel?.font = UIFont.latoSemiBold(13) | |
button?.backgroundColor = UIColor.creditSesameCyan | |
button?.setTitle(NSLocalizedString("Search All Credit Cards", comment: "More Cards"), for: .normal) | |
view?.addTopSeparator() | |
button?.addTarget(self, action: #selector(viewMoreCards), for: .touchUpInside) | |
return view | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
switch currentTab { | |
case .creditCards: | |
let creditCards = creditCardSections[indexPath.section] | |
let creditCard = creditCards[indexPath.row] | |
var creditCardCell: ClickApplyCell? = nil | |
var pagePosition: String | |
pagePosition = AnalyticsPagePosition.bestCards | |
if CreditSesameRestClient.shared.canShowCreditCardsFilter, TestingManager.shared.newCCFilteringVariation == Variations.variation { | |
let filterCategory = FilterCategory(rawValue: lastFilterSelected) ?? .bestCards | |
pagePosition = filterCategory.pagePosition | |
} | |
creditCardCell = cellForCreditCard(creditCard: creditCard, offerType: .estimatedCreditLimit) | |
creditCardCell?.contentView.tag = indexPath.row | |
let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1 | |
creditCardCell?.cellPosition = "\(offerPosition)" | |
creditCardCell?.pagePosition = pagePosition | |
creditCardCell?.offer = creditCard | |
creditCardCell?.selectionStyle = .none | |
creditCardCell?.addTopSeparator() | |
trackViewOfferCreditCard(creditCard: creditCard, pagePosition: pagePosition, pageLocation: nil, offerPosition: creditCardCell?.cellPosition!) | |
return creditCardCell! | |
case .personalLoans: | |
if let loan = personalLoan { | |
let personalLoanCell = cellForPersonalLoan(pL: loan, offerType: loan.offerType) | |
let offerPosition = numberOfOffersTill(section: indexPath.section, tableView: tableView) + indexPath.row + 1 | |
personalLoanCell.cellPosition = "\(offerPosition)" | |
personalLoanCell.pagePosition = nil | |
personalLoanCell.pageLocation = nil | |
personalLoanCell.offer = loan | |
personalLoanCell.selectionStyle = .none | |
trackViewOfferPersonalLoan(personalLoan: personalLoan!, pagePosition: nil, pageLocation: nil, offerPosition: "1") | |
return personalLoanCell | |
} | |
else if let cell = tableView.dequeueReusableCell(withIdentifier: notFoundIdentifier) { | |
for v in cell.contentView.subviews { | |
v.removeFromSuperview() | |
} | |
let view = UIView.loadNib("OffersNotFoundView") | |
let titleLabel = view.labelWithTag(10) | |
let contentLabel = view.labelWithTag(11) | |
let actionView = view.viewWithTag(20) | |
let actionButton = view.buttonWithTag(21) | |
let accessibilityView = view.viewWithTag(30)! | |
titleLabel?.font = UIFont.latoHeavy(18) | |
titleLabel?.textColor = UIColor.init(rgb: 0x606060) | |
titleLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundTitle ?? NSLocalizedString("Loans Offer Not Found title", comment: "Not found title") | |
contentLabel?.font = UIFont.lato(14) | |
contentLabel?.textColor = UIColor.init(rgb: 0x606060) | |
contentLabel?.textAlignment = .left | |
contentLabel?.text = ClientConfigurationManager.shared.configurationFile?.disclaimers?.loansNotFoundContent ?? NSLocalizedString("Loans Offer Not Found content", comment: "Not found content") | |
contentLabel?.numberOfLines = 0 | |
contentLabel?.lineBreakMode = .byWordWrapping | |
actionView?.isHidden = false | |
let buttonTitle = currentTab == .creditCards ? NSLocalizedString("Search All Credit Cards", comment: "Market place button") : NSLocalizedString("Search All Personal Loans", comment: "Market place button") | |
actionButton?.setThemeInfoButton(title: buttonTitle) | |
let selector = currentTab == .creditCards ? #selector(openCreditCardsMarketplace) : #selector(openPersonalLoansMarketplace) | |
actionButton?.addTarget(self, action: selector, for: .touchUpInside) | |
cell.contentView.addSubview(view) | |
view.snp.makeConstraints({ make in | |
make.edges.equalToSuperview() | |
}) | |
cell.selectionStyle = .none | |
cell.backgroundColor = UIColor.creditSesameLightGrayBackgroundColor | |
accessibilityView.isAccessibilityElement = true | |
accessibilityView.accessibilityLabel = "\(titleLabel?.text ?? ""): \(contentLabel?.text ?? "")" | |
return cell | |
} | |
} | |
return UITableViewCell() | |
} | |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
tableView.deselectRow(at: indexPath, animated: true) | |
} | |
} | |
extension BestOffersViewController: UITextFieldDelegate { | |
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { | |
textField.text = "\(textField.text?.removeMoneyFormat().intValue ?? 0)" | |
if textField == self.loanAmountTextField { | |
trackClick(clickType: AnalyticsClickType.enterLoanAmount, pagePosition: nil) | |
} | |
// update annual income | |
if textField == self.annualIncomeTextField { | |
trackClick(clickType: AnalyticsClickType.updateIncome, pagePosition: nil) | |
} | |
return true | |
} | |
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { | |
let currentString = textField.text! as NSString | |
let newString = currentString.replacingCharacters(in: range, with: string) as NSString | |
if let textField = textField as? TextField, let maxLength = textField.maxCharacters, newString.length > maxLength { | |
return false | |
} | |
if let timer = timer { | |
timer.startTimer() | |
} | |
else { | |
timer = CSTimer() | |
timer?.action = { | |
if (self.annualIncomeTextField?.text?.count ?? 0) == 0 || (self.loanAmountTextField?.text?.count ?? 0) == 0 { | |
return | |
} | |
self.loadPersonalLoanIfNeeded(isInputChange: true) | |
DispatchQueue.main.async { | |
self.hideKeyboard() | |
} | |
} | |
timer?.startTimer() | |
} | |
return true | |
} | |
func textFieldDidEndEditing(_ textField: UITextField) { | |
let money = textField.text?.removeMoneyFormat().doubleValue ?? 0 | |
// update amount needed | |
if textField == self.loanAmountTextField { | |
guard money >= 0 && money <= 100000 else { | |
let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorLoanAmount ?? NSLocalizedString("AmountNeededTooltip", comment: "amount loan error") | |
showAppClientError(message) | |
textField.text = String.moneyFormattedString(number: NSNumber(value: money)) | |
amountInputError = true | |
return | |
} | |
amountInputError = false | |
loanAmount = Int(money) | |
} | |
// update annual income | |
if textField == self.annualIncomeTextField { | |
guard money > 0 else { | |
let message = ClientConfigurationManager.shared.configurationFile?.errorValidation?.errorAnnualIncome ?? NSLocalizedString("CalculateDTIIncomeError", comment: "invalid income error") | |
showAppClientError(message) | |
textField.text = String.moneyFormattedString(number: NSNumber(value: money)) | |
incomeInputError = true | |
return | |
} | |
incomeInputError = false | |
let user = CreditSesameRestClient.shared.user?.copy() as? User ?? User() | |
if user.annualIncome?.doubleValue != money { | |
user.annualIncome = NSNumber(value: money) | |
CreditSesameRestClient.shared.updateUser(user: user, password: AppContext.shared.password) | |
} | |
} | |
textField.text = String.moneyFormattedString(number: NSNumber(value: money)) | |
} | |
} | |
extension BestOffersViewController: DGScrollableSegmentControlDataSource,DGScrollableSegmentControlDelegate { | |
func numbersOfItem() -> Int { | |
return filters.count | |
} | |
func itemfor(_ index: Int) -> DGItem { | |
let item = DGItem() | |
item.setTitle(filters[index].title, for: .normal) | |
item.isSelected = index == lastFilterSelected | |
item.setImage(UIImage(named: filters[index].imageName), for: .normal) | |
item.titleLabel?.font = UIFont.latoSemiBold(12) | |
if item.isSelected { | |
item.setTitleColor(UIColor.white, for: .normal) | |
item.backgroundColor = UIColor.creditSesameCyan | |
} else { | |
item.setTitleColor(UIColor.creditSesameCyan, for: .normal) | |
item.backgroundColor = UIColor.white | |
} | |
item.updateBorder() | |
return item | |
} | |
func didSelect(_ item: DGItem, atIndex index: Int) { | |
lastFilterSelected = index | |
let filterCategory = FilterCategory(rawValue: lastFilterSelected) ?? .bestCards | |
loadData(index: filterCategory) | |
switch filterCategory { | |
case .bestCards: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.bestCards) | |
case .cashBack: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.cashBack) | |
case .noAnnualFee: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.noAnnualFee) | |
case .introPurchaseAPR: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.introPurchaseAPR) | |
case .rewards: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.rewards) | |
case .balanceTransfer: | |
trackClick(clickType: AnalyticsClickType.filter, pagePosition: AnalyticsPagePosition.balanceTransfer) | |
} | |
} | |
} | |
struct FilterData { | |
var title = "" | |
var imageName = "" | |
init(title: String, imageName: String) { | |
self.title = title | |
self.imageName = imageName | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment