Skip to content

Instantly share code, notes, and snippets.

@FabiolaRamirez
Created June 6, 2019 19:17
Show Gist options
  • Save FabiolaRamirez/de17d2b3481e90634fd2a5fead3d8638 to your computer and use it in GitHub Desktop.
Save FabiolaRamirez/de17d2b3481e90634fd2a5fead3d8638 to your computer and use it in GitHub Desktop.
//
// 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