Skip to content

Instantly share code, notes, and snippets.

@daryadariaa
Last active November 6, 2019 19:17
Show Gist options
  • Save daryadariaa/eae0a53ca9e05f698ae9ee43678191af to your computer and use it in GitHub Desktop.
Save daryadariaa/eae0a53ca9e05f698ae9ee43678191af to your computer and use it in GitHub Desktop.
import UIKit
import RxSwift
import RxCocoa
protocol AddDiscountTableViewCellDelegate: class {
func didAdd(_ discount: DiscountViewModel)
func didCancel(_ discount: DiscountViewModel)
func didModify(_ discount: DiscountViewModel)
func didRequest(present dropDown: SelectionDropDownView, options: [DropdownItem])
func didRequestAvailableProducts() -> [SelectedProductViewModel]
}
class AddDiscountTableViewCell: UITableViewCell {
@IBOutlet weak var discountTypeDropDown: SelectionDropDownView!
@IBOutlet weak var amountTextField: PrimaryTextField!
@IBOutlet weak var itemsDropDown: SelectionDropDownView!
@IBOutlet weak var cancelButton: UIButton!
static var identifier = "AddDiscountTableViewCell"
private var disposeBag = DisposeBag()
var viewModel: DiscountViewModel! {
didSet {
bind()
update()
verify()
}
}
weak var delegate: AddDiscountTableViewCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
configureView()
}
private func configureView() {
discountTypeDropDown.placeholder = "discount".localized()
amountTextField.placeholder = "amount".localized()
itemsDropDown.placeholder = "item".localized()
itemsDropDown.type = .checkmark
}
private func bind() {
disposeBag = DisposeBag()
discountTypeDropDown.value = viewModel.discountType?.title
amountTextField.text = "\(String(describing: viewModel.amount))"
itemsDropDown.value = String(format: "items-count".localized(), NSNumber(value: viewModel.productIds.count))
amountTextField.rx.value.subscribe(onNext: { [unowned self] text in
guard let text = text, let value = Double(text) else {
return
}
self.viewModel.amount = value
self.verify()
}).disposed(by: disposeBag)
discountTypeDropDown.rx.tap.subscribe(onNext: { [unowned self] in
let types = ProductDiscountType.allCases
let options = types.map {
DropdownItem(id: $0.id, title: $0.title)
}
self.delegate?.didRequest(present: self.discountTypeDropDown, options: options)
}).disposed(by: disposeBag)
itemsDropDown.rx.tap.subscribe(onNext: { [unowned self] in
guard let products = self.delegate?.didRequestAvailableProducts() else {
return
}
let options = products.map {
DropdownItem(id: $0.id, title: $0.name, subtitle: $0.details)
}
self.delegate?.didRequest(present: self.itemsDropDown, options: options)
}).disposed(by: disposeBag)
cancelButton.rx.tap.subscribe(onNext: {
self.delegate?.didCancel(self.viewModel)
}).disposed(by: disposeBag)
discountTypeDropDown.delegate = self
itemsDropDown.delegate = self
}
private func verify() {
if viewModel.isReady && !viewModel.isVerified {
delegate?.didAdd(viewModel)
viewModel.isVerified = true
}
}
private func update() {
cancelButton.isHidden = !viewModel.isReady
}
}
extension AddDiscountTableViewCell: SelectionDropDownViewDelegate {
func didSelectItem(dropDown: SelectionDropDownView, item: DropdownItem) {
if dropDown == discountTypeDropDown {
didSelectDiscountType(item: item)
} else if dropDown == itemsDropDown {
didCheckedProductItems(items: dropDown.selectedItems)
}
verify()
}
func didDeselectItem(dropDown: SelectionDropDownView, item: DropdownItem) {
}
private func didSelectDiscountType(item: DropdownItem) {
viewModel.discountType = ProductDiscountType(item.id)!
}
private func didCheckedProductItems(items: [DropdownItem]) {
viewModel.productIds = items.map {
$0.id
}
delegate?.didModify(viewModel)
}
}
protocol AddDiscountViewControllerDelegate: class {
func didAdd(_ discounts: [DiscountViewModel])
}
class AddDiscountViewController: BaseViewController, Storyboardable {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var applyButton: PrimaryButton!
private var discounts = [DiscountViewModel]()
private var remainingProducts = [SelectedProductViewModel]()
private var disposeBag = DisposeBag()
var viewModel: AddDiscountViewModel!
weak var delegate: AddDiscountViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
bind()
configureView()
remainingProducts = viewModel.selections
}
private func configureView() {
parent?.title = discounts.isEmpty ? "add-discount".localized() : "edit-discount".localized()
}
private func bind() {
applyButton.rx.tap.subscribe(onNext: {
self.delegate?.didAdd(self.discounts)
}).disposed(by: disposeBag)
}
}
extension AddDiscountViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return discounts.count + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: AddDiscountTableViewCell.identifier, for: indexPath) as? AddDiscountTableViewCell else {
return UITableViewCell()
}
if discounts.count > 0 {
cell.viewModel = discounts[indexPath.row - 1]
}
cell.viewModel = DiscountViewModel()
cell.delegate = self
return cell
}
}
extension AddDiscountViewController: UITableViewDelegate {
}
extension AddDiscountViewController: AddDiscountTableViewCellDelegate {
func didModify(_ discount: DiscountViewModel) {
let ids = discount.productIds
ids.forEach { id in
remainingProducts = remainingProducts.filter {
$0.id != id
}
}
}
func didRequest(present dropDown: SelectionDropDownView, options: [DropdownItem]) {
dropDown.present(in: self, options: options)
}
func didRequestAvailableProducts() -> [SelectedProductViewModel] {
return remainingProducts
}
func didCancel(_ discount: DiscountViewModel) {
guard let index = discounts.firstIndex(where: {
$0 === discount
}) else {
return
}
discounts.remove(at: index)
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .right)
}
func didAdd(_ discountViewModel: DiscountViewModel) {
discounts.append(discountViewModel)
tableView.reloadData()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment