Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shop configs #179

Merged
merged 13 commits into from
Jun 8, 2018
8 changes: 4 additions & 4 deletions ShopApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@
0B83DFFD204EC0130037035D /* AccountFooterViewSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83DFFC204EC0130037035D /* AccountFooterViewSpec.swift */; };
0B83DFFF204EC0750037035D /* AccountFooterDelegateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83DFFE204EC0750037035D /* AccountFooterDelegateMock.swift */; };
0B83E001204EC3AC0037035D /* AccountNotLoggedHeaderDelegateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83E000204EC3AC0037035D /* AccountNotLoggedHeaderDelegateMock.swift */; };
0B83E003204EC4600037035D /* AccountLoggedHeaderDelegateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83E002204EC4600037035D /* AccountLoggedHeaderDelegateMock.swift */; };
0B83E005204EC4E20037035D /* AccountNotLoggedHeaderViewSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83E004204EC4E20037035D /* AccountNotLoggedHeaderViewSpec.swift */; };
0B83E007204EC5830037035D /* AccountLoggedHeaderViewSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83E006204EC5830037035D /* AccountLoggedHeaderViewSpec.swift */; };
0B83E00A20504AA10037035D /* GridCollectionViewControllerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B83E00920504AA10037035D /* GridCollectionViewControllerSpec.swift */; };
Expand Down Expand Up @@ -307,6 +306,7 @@
0BD75361201F520700AB1FED /* CartTableProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BD75360201F520700AB1FED /* CartTableProvider.swift */; };
0BD75363201F6D1F00AB1FED /* AddAddressUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BD75362201F6D1F00AB1FED /* AddAddressUseCase.swift */; };
0BD75365201F6D2B00AB1FED /* UpdateDefaultAddressUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BD75364201F6D2B00AB1FED /* UpdateDefaultAddressUseCase.swift */; };
0BE105AC20C6811600C3DDC1 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE105AB20C6811600C3DDC1 /* Config.swift */; };
0BE654722097320A008AFD5E /* GetProductListResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE654712097320A008AFD5E /* GetProductListResponse.swift */; };
0BE6547420973479008AFD5E /* GetProductResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE6547320973479008AFD5E /* GetProductResponse.swift */; };
0BE6547620973606008AFD5E /* CustomAttributeResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE6547520973606008AFD5E /* CustomAttributeResponse.swift */; };
Expand Down Expand Up @@ -959,7 +959,6 @@
0B83DFFC204EC0130037035D /* AccountFooterViewSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountFooterViewSpec.swift; sourceTree = "<group>"; };
0B83DFFE204EC0750037035D /* AccountFooterDelegateMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountFooterDelegateMock.swift; sourceTree = "<group>"; };
0B83E000204EC3AC0037035D /* AccountNotLoggedHeaderDelegateMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountNotLoggedHeaderDelegateMock.swift; sourceTree = "<group>"; };
0B83E002204EC4600037035D /* AccountLoggedHeaderDelegateMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLoggedHeaderDelegateMock.swift; sourceTree = "<group>"; };
0B83E004204EC4E20037035D /* AccountNotLoggedHeaderViewSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountNotLoggedHeaderViewSpec.swift; sourceTree = "<group>"; };
0B83E006204EC5830037035D /* AccountLoggedHeaderViewSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountLoggedHeaderViewSpec.swift; sourceTree = "<group>"; };
0B83E00920504AA10037035D /* GridCollectionViewControllerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridCollectionViewControllerSpec.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1081,6 +1080,7 @@
0BD75360201F520700AB1FED /* CartTableProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CartTableProvider.swift; sourceTree = "<group>"; };
0BD75362201F6D1F00AB1FED /* AddAddressUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAddressUseCase.swift; sourceTree = "<group>"; };
0BD75364201F6D2B00AB1FED /* UpdateDefaultAddressUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateDefaultAddressUseCase.swift; sourceTree = "<group>"; };
0BE105AB20C6811600C3DDC1 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
0BE654712097320A008AFD5E /* GetProductListResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetProductListResponse.swift; sourceTree = "<group>"; };
0BE6547320973479008AFD5E /* GetProductResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetProductResponse.swift; sourceTree = "<group>"; };
0BE6547520973606008AFD5E /* CustomAttributeResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAttributeResponse.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1878,7 +1878,6 @@
0B5768C520494EEA0001738D /* Mocks */ = {
isa = PBXGroup;
children = (
0B83E002204EC4600037035D /* AccountLoggedHeaderDelegateMock.swift */,
0B83E000204EC3AC0037035D /* AccountNotLoggedHeaderDelegateMock.swift */,
0B437175204D783400C086CF /* OrderHeaderDelegateMock.swift */,
);
Expand Down Expand Up @@ -4407,6 +4406,7 @@
8E5EFAFB2035F34300FD718B /* CartProduct.swift */,
8E5EFB0A2035F34300FD718B /* Category.swift */,
8E5EFB0D2035F34300FD718B /* Checkout.swift */,
0BE105AB20C6811600C3DDC1 /* Config.swift */,
8E5EFB062035F34300FD718B /* Country.swift */,
8E5EFAFA2035F34300FD718B /* CreditCard.swift */,
8E5EFB002035F34300FD718B /* Customer.swift */,
Expand Down Expand Up @@ -4992,7 +4992,6 @@
0BA5DC232073AFC600668C99 /* UpdateAddressUseCaseSpec.swift in Sources */,
614C80C22046DC63006A99E0 /* BaseTableViewControllerSpec.swift in Sources */,
6104CD0D2065358300B780A0 /* UIImageView+NetworkSpec.swift in Sources */,
0B83E003204EC4600037035D /* AccountLoggedHeaderDelegateMock.swift in Sources */,
0BEAE1A420724B22001AE4F8 /* OrderListUseCaseSpec.swift in Sources */,
0B437172204D782300C086CF /* OrderListEmptyDataViewDelegateMock.swift in Sources */,
0B5768CF204D3B040001738D /* AddressFormViewControllerSpec.swift in Sources */,
Expand Down Expand Up @@ -5537,6 +5536,7 @@
8E5EFB2E2035F34400FD718B /* OrderItem.swift in Sources */,
8E5EFB262035F34400FD718B /* ProductVariant.swift in Sources */,
8E5EFB252035F34400FD718B /* State.swift in Sources */,
0BE105AC20C6811600C3DDC1 /* Config.swift in Sources */,
0B1AB004206A46C100A24E5B /* API.swift in Sources */,
8E5EFB2B2035F34400FD718B /* SortingValue.swift in Sources */,
8E5EFB2F2035F34400FD718B /* Checkout.swift in Sources */,
Expand Down
29 changes: 14 additions & 15 deletions ShopApp/App/Modules/Account/Controllers/AccountViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import UIKit

import ShopApp_Gateway

class AccountViewController: BaseViewController<AccountViewModel>, AccountTableProviderDelegate, AccountNotLoggedHeaderDelegate, AccountLoggedHeaderDelegate, AccountFooterDelegate {
class AccountViewController: BaseViewController<AccountViewModel>, AccountTableProviderDelegate, AccountNotLoggedHeaderDelegate, AccountFooterDelegate {
@IBOutlet private weak var tableView: UITableView!

private var selectedPolicy: Policy?

var tableProvider: AccountTableProvider!
var isOrdersEnabled: Bool!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You inject this value to view controller and then pass it to the provider, but you can inject it directly to a provider


// MARK: - View controller lifecycle

Expand Down Expand Up @@ -61,6 +62,7 @@ class AccountViewController: BaseViewController<AccountViewModel>, AccountTableP
tableView.registerNibForCell(AccountTableViewCell.self)
tableView.registerNibForHeaderFooterView(AccountFooterView.self)

tableProvider.isOrdersEnabled = isOrdersEnabled
tableProvider.delegate = self
tableView.dataSource = tableProvider
tableView.delegate = tableProvider
Expand Down Expand Up @@ -97,6 +99,17 @@ class AccountViewController: BaseViewController<AccountViewModel>, AccountTableP

// MARK: - AccountTableProviderDelegate

func provider(_ provider: AccountTableProvider, didSelect type: AccountCustomerSection) {
switch type {
case .orders:
performSegue(withIdentifier: SegueIdentifiers.toOrderList, sender: self)
case .info:
performSegue(withIdentifier: SegueIdentifiers.toPersonalInfo, sender: self)
default:
performSegue(withIdentifier: SegueIdentifiers.toAccountAddressList, sender: self)
}
}

func provider(_ provider: AccountTableProvider, didSelect policy: Policy) {
selectedPolicy = policy
performSegue(withIdentifier: SegueIdentifiers.toPolicy, sender: self)
Expand All @@ -112,20 +125,6 @@ class AccountViewController: BaseViewController<AccountViewModel>, AccountTableP
performSegue(withIdentifier: SegueIdentifiers.toSignUp, sender: self)
}

// MARK: - AccountLoggedHeaderDelegate

func headerViewDidTapMyOrders(_ headerView: AccountLoggedHeaderView) {
performSegue(withIdentifier: SegueIdentifiers.toOrderList, sender: self)
}

func headerViewDidTapPersonalInfo(_ headerView: AccountLoggedHeaderView) {
performSegue(withIdentifier: SegueIdentifiers.toPersonalInfo, sender: self)
}

func headerViewDidTapShippingAddress(_ headerView: AccountLoggedHeaderView) {
performSegue(withIdentifier: SegueIdentifiers.toAccountAddressList, sender: self)
}

// MARK: - AccountFooterViewDelegate

func footerViewDidTapLogout(_ footerView: AccountFooterView) {
Expand Down
2 changes: 2 additions & 0 deletions ShopApp/App/Modules/Account/DI/AccountAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Swinject
import ShopApp_Gateway

class AccountAssembly: Assembly {
func assemble(container: Container) {
Expand All @@ -33,6 +34,7 @@ class AccountAssembly: Assembly {
container.storyboardInitCompleted(AccountViewController.self) { r, c in
c.viewModel = r.resolve(AccountViewModel.self)!
c.tableProvider = r.resolve(AccountTableProvider.self)!
c.isOrdersEnabled = r.resolve(Config.self)!.isOrdersEnabled
}

container.storyboardInitCompleted(ForgotPasswordViewController.self) { r, c in
Expand Down
97 changes: 84 additions & 13 deletions ShopApp/App/Modules/Account/Providers/AccountTableProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,57 @@ import UIKit

import ShopApp_Gateway

private enum AccountSection: Int {
case customer
case policy

static let allValues = [customer, policy]
}

enum AccountCustomerSection: Int {
case orders
case info
case addresses

static let allValues = [orders, info, addresses]
}

protocol AccountTableProviderDelegate: class {
func provider(_ provider: AccountTableProvider, didSelect type: AccountCustomerSection)
func provider(_ provider: AccountTableProvider, didSelect policy: Policy)
}

class AccountTableProvider: NSObject, UITableViewDataSource, UITableViewDelegate {
private let kSpaceBetweenSections: CGFloat = 10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private let properties inside class should not have prefix 'k'


var policies: [Policy] = []
var customer: Customer?
var isOrdersEnabled = false

weak var delegate: (AccountTableProviderDelegate & AccountNotLoggedHeaderDelegate & AccountLoggedHeaderDelegate & AccountFooterDelegate)?
weak var delegate: (AccountTableProviderDelegate & AccountNotLoggedHeaderDelegate & AccountFooterDelegate)?

// MARK: - UITableViewDataSource

func numberOfSections(in tableView: UITableView) -> Int {
return AccountSection.allValues.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return policies.count
return section == AccountSection.customer.rawValue ? numberOfRowsInHeaderSection() : policies.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: AccountTableViewCell = tableView.dequeueReusableCellForIndexPath(indexPath)
let policy = policies[indexPath.row]
cell.configure(with: policy)

switch indexPath.section {
case AccountSection.customer.rawValue:
let type = typeOfIndexPath(indexPath)
cell.configure(with: type)
default:
let policy = policies[indexPath.row]
cell.configure(with: policy)
}

return cell
}

Expand All @@ -39,36 +70,76 @@ class AccountTableProvider: NSObject, UITableViewDataSource, UITableViewDelegate
guard let delegate = delegate else {
return
}
let policy = policies[indexPath.row]
delegate.provider(self, didSelect: policy)

switch indexPath.section {
case AccountSection.customer.rawValue:
let type = typeOfIndexPath(indexPath)
delegate.provider(self, didSelect: type)
default:
let policy = policies[indexPath.row]
delegate.provider(self, didSelect: policy)
}
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return customer != nil ? kAccountLoggedHeaderViewHeight : kAccountNotLoggedHeaderViewHeight
switch section {
case AccountSection.customer.rawValue:
return customer != nil ? kAccountLoggedHeaderViewHeight : kAccountNotLoggedHeaderViewHeight
default:
return kSpaceBetweenSections
}
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return customer != nil ? kAccountFooterViewHeight : TableView.headerFooterMinHeight
switch section {
case AccountSection.customer.rawValue:
return TableView.headerFooterMinHeight
default:
return customer != nil ? kAccountFooterViewHeight : TableView.headerFooterMinHeight
}
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard section == AccountSection.customer.rawValue else {
return UIView()
}

if let customer = customer {
let view = AccountLoggedHeaderView(frame: CGRect.zero, customer: customer)
view.delegate = delegate
return view
} else {
let view = AccountNotLoggedHeaderView(frame: CGRect.zero)
view.delegate = delegate
return view
}
}

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
guard customer != nil else {
guard section == AccountSection.policy.rawValue, customer != nil else {
return UIView()
}
let view: AccountFooterView = tableView.dequeueReusableHeaderFooterView()
view.delegate = delegate
return view
}

private func numberOfRowsInHeaderSection() -> Int {
guard customer != nil else {
return 0
}

var numberOfRows = AccountCustomerSection.allValues.count

if !isOrdersEnabled {
numberOfRows -= 1
}

return numberOfRows
}

private func typeOfIndexPath(_ indexPath: IndexPath) -> AccountCustomerSection {
let index = isOrdersEnabled ? indexPath.row : indexPath.row + 1

return AccountCustomerSection(rawValue: index)!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import ShopApp_Gateway
class AccountTableViewCell: UITableViewCell {
@IBOutlet private weak var policyTitleLabel: UILabel!

var type: AccountCustomerSection?

// MARK: - View lifecycle

override func awakeFromNib() {
Expand All @@ -23,6 +25,19 @@ class AccountTableViewCell: UITableViewCell {

// MARK: - Setup

func configure(with type: AccountCustomerSection) {
self.type = type

switch type {
case .orders:
policyTitleLabel.text = "Button.MyOrders".localizable
case .info:
policyTitleLabel.text = "Button.PersonalInfo".localizable
default:
policyTitleLabel.text = "Button.ShippingAddress".localizable
}
}

func configure(with policy: Policy) {
policyTitleLabel.text = policy.title
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ShopApp_Gateway

private let kAvatarTextSizeFactor: CGFloat = 0.4

let kAccountLoggedHeaderViewHeight: CGFloat = 312
let kAccountLoggedHeaderViewHeight: CGFloat = 109

private struct CustomerImageConfig: AvatarImageViewConfiguration {
let shape: Shape = .circle
Expand All @@ -29,27 +29,16 @@ private struct CustomerImageDataSource: AvatarImageViewDataSource {
}
}

protocol AccountLoggedHeaderDelegate: class {
func headerViewDidTapMyOrders(_ headerView: AccountLoggedHeaderView)
func headerViewDidTapPersonalInfo(_ headerView: AccountLoggedHeaderView)
func headerViewDidTapShippingAddress(_ headerView: AccountLoggedHeaderView)
}

class AccountLoggedHeaderView: UIView {
@IBOutlet private weak var myOrdersButton: UIButton!
@IBOutlet private weak var personalInfoButton: UIButton!
@IBOutlet private weak var welcomeLabel: UILabel!
@IBOutlet private weak var customerNameLabel: UILabel!
@IBOutlet private weak var shippingAddressButton: UIButton!

@IBOutlet private weak var customerImageView: AvatarImageView! {
didSet {
customerImageView.configuration = CustomerImageConfig()
}
}

weak var delegate: AccountLoggedHeaderDelegate?

// MARK: - View lifecycle

init(frame: CGRect, customer: Customer) {
Expand All @@ -73,28 +62,11 @@ class AccountLoggedHeaderView: UIView {
}

private func setupViews() {
myOrdersButton.setTitle("Button.MyOrders".localizable, for: .normal)
personalInfoButton.setTitle("Button.PersonalInfo".localizable, for: .normal)
shippingAddressButton.setTitle("Button.ShippingAddress".localizable, for: .normal)
welcomeLabel.text = "Label.Welcome".localizable
}

private func populateViews(customer: Customer) {
customerNameLabel.text = customer.fullName
customerImageView.dataSource = CustomerImageDataSource(customerName: customer.fullName)
}

// MARK: - Actions

@IBAction func myOrdersButtonDidPress(_ sender: UIButton) {
delegate?.headerViewDidTapMyOrders(self)
}

@IBAction func personalInfoButtonDidPress(_ sender: UIButton) {
delegate?.headerViewDidTapPersonalInfo(self)
}

@IBAction func shippingAddressButtonDidPress(_ sender: UIButton) {
delegate?.headerViewDidTapShippingAddress(self)
}
}
Loading