// // ViewController.swift // EmployeeDirectory // // Created by Matt Bruce on 1/20/25. // import UIKit import Combine class EmployeesViewController: UIViewController { private let tableView = UITableView() private let activityIndicator = UIActivityIndicatorView(style: .large) private let viewModel = EmployeesViewModel() private var cancellables = Set() public override func viewDidLoad() { super.viewDidLoad() setupUI() bindViewModel() viewModel.changeMode(to: .empty) //viewModel.fetchEmployees() } private func setupUI() { view.backgroundColor = .white // Configure TableView tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") tableView.dataSource = self view.addSubview(tableView) tableView.frame = view.bounds // Configure Activity Indicator activityIndicator.center = view.center view.addSubview(activityIndicator) } private func bindViewModel() { viewModel.$employees .receive(on: RunLoop.main) .sink { [weak self] _ in self?.updateFooter() self?.tableView.reloadData() self?.tableView.refreshControl?.endRefreshing() } .store(in: &cancellables) viewModel.$isLoading .receive(on: RunLoop.main) .sink { [weak self] isLoading in if isLoading { self?.activityIndicator.startAnimating() } else { self?.activityIndicator.stopAnimating() } } .store(in: &cancellables) viewModel.$errorMessage .receive(on: RunLoop.main) .sink { [weak self] _ in self?.updateFooter() } .store(in: &cancellables) } private func updateFooter() { var message: String? { guard !viewModel.isLoading else { return nil } return viewModel.errorMessage ?? (viewModel.employees.isEmpty ? "No employees found, please try to refresh." : nil) } if let message, !viewModel.isLoading { let footerView = UILabel() footerView.font = .systemFont(ofSize: 17, weight: .medium) footerView.text = message footerView.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 150) tableView.tableFooterView = footerView } else { tableView.tableFooterView = nil } } } extension EmployeesViewController: UITableViewDataSource { public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return viewModel.employees.count } public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let employee = viewModel.employees[indexPath.row] cell.textLabel?.text = employee.fullName cell.detailTextLabel?.text = employee.emailAddress return cell } }