Compare commits
No commits in common. "7b65685d1a90424c70724c0ef17421fb2115cede" and "c2768a486427ea49b29103444af83febcdb801c9" have entirely different histories.
7b65685d1a
...
c2768a4864
@ -1,99 +0,0 @@
|
|||||||
//
|
|
||||||
// EmployeeDetailViewController.swift
|
|
||||||
// EmployeeDirectory
|
|
||||||
//
|
|
||||||
// Created by Matt Bruce on 2/6/25.
|
|
||||||
//
|
|
||||||
import UIKit
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
public class EmployeeDetailViewController: UIViewController {
|
|
||||||
|
|
||||||
private let photoImageView = UIImageView()
|
|
||||||
private let nameLabel = UILabel()
|
|
||||||
private let emailLabel = UILabel()
|
|
||||||
private let teamLabel = UILabel()
|
|
||||||
private let employeeTypeLabel = UILabel()
|
|
||||||
private let phoneLabel = UILabel()
|
|
||||||
private let bioLabel = UILabel()
|
|
||||||
private let stackView = UIStackView()
|
|
||||||
private let scrollView = UIScrollView()
|
|
||||||
|
|
||||||
/// Used for grabbing the photo
|
|
||||||
private var largerPhotoSubscriber: AnyCancellable?
|
|
||||||
|
|
||||||
public var viewModel: EmployeeDetailViewModel?
|
|
||||||
|
|
||||||
public override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
view.backgroundColor = .white
|
|
||||||
|
|
||||||
// default image
|
|
||||||
photoImageView.image = UIImage(systemName: "person.crop.circle")
|
|
||||||
photoImageView.contentMode = .scaleAspectFit
|
|
||||||
|
|
||||||
// Configure stackView
|
|
||||||
stackView.axis = .vertical
|
|
||||||
stackView.spacing = 5
|
|
||||||
stackView.alignment = .top
|
|
||||||
stackView.distribution = .fill
|
|
||||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
|
|
||||||
// Add labels to stackView
|
|
||||||
stackView.addArrangedSubview(photoImageView)
|
|
||||||
stackView.addArrangedSubview(nameLabel)
|
|
||||||
stackView.addArrangedSubview(teamLabel)
|
|
||||||
stackView.addArrangedSubview(employeeTypeLabel)
|
|
||||||
stackView.addArrangedSubview(phoneLabel)
|
|
||||||
stackView.addArrangedSubview(emailLabel)
|
|
||||||
stackView.addArrangedSubview(bioLabel)
|
|
||||||
|
|
||||||
view.addSubview(stackView)
|
|
||||||
photoImageView.heightAnchor.constraint(equalToConstant: 200).isActive = true
|
|
||||||
photoImageView.widthAnchor.constraint(equalToConstant: 200).isActive = true
|
|
||||||
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
|
|
||||||
stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
|
|
||||||
stackView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 10).isActive = true
|
|
||||||
stackView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
|
|
||||||
|
|
||||||
// Bind the image to the photoImageView
|
|
||||||
largerPhotoSubscriber = viewModel?.$largePhoto
|
|
||||||
.compactMap { $0 }
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.sink { [weak self] image in
|
|
||||||
self?.photoImageView.image = image
|
|
||||||
}
|
|
||||||
|
|
||||||
if let viewModel {
|
|
||||||
// Bind data to UI components
|
|
||||||
nameLabel.text = viewModel.fullName
|
|
||||||
emailLabel.text = viewModel.emailAddress
|
|
||||||
teamLabel.text = viewModel.team
|
|
||||||
employeeTypeLabel.text = viewModel.employeeType
|
|
||||||
phoneLabel.text = viewModel.phoneNumber
|
|
||||||
bioLabel.text = viewModel.biography
|
|
||||||
|
|
||||||
// Dynamically show or hide elements based on their content
|
|
||||||
phoneLabel.isHidden = viewModel.phoneNumber == nil
|
|
||||||
bioLabel.isHidden = viewModel.biography == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let phoneTap = UITapGestureRecognizer(target: self, action: #selector(didTapPhoneView(_:)))
|
|
||||||
phoneLabel.isUserInteractionEnabled = true
|
|
||||||
phoneLabel.addGestureRecognizer(phoneTap)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func didTapPhoneView(_ sender: UITapGestureRecognizer) {
|
|
||||||
guard let phoneNumber = viewModel?.phoneNumber?.filter({ $0.isNumber }) else {
|
|
||||||
print("phone not there")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let numberUrl = URL(string: "tel://\(phoneNumber)")!
|
|
||||||
if UIApplication.shared.canOpenURL(numberUrl) {
|
|
||||||
UIApplication.shared.open(numberUrl)
|
|
||||||
}
|
|
||||||
print("print", phoneNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -73,7 +73,6 @@ class EmployeesViewController: UIViewController {
|
|||||||
tableView.register(EmployeeTableViewCell.self, forCellReuseIdentifier: EmployeeTableViewCell.identifier)
|
tableView.register(EmployeeTableViewCell.self, forCellReuseIdentifier: EmployeeTableViewCell.identifier)
|
||||||
view.addSubview(tableView)
|
view.addSubview(tableView)
|
||||||
tableView.frame = view.bounds
|
tableView.frame = view.bounds
|
||||||
tableView.delegate = self
|
|
||||||
|
|
||||||
//add pull to refresh
|
//add pull to refresh
|
||||||
tableView.refreshControl = UIRefreshControl()
|
tableView.refreshControl = UIRefreshControl()
|
||||||
@ -141,15 +140,6 @@ class EmployeesViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EmployeesViewController: UITableViewDelegate{
|
|
||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
let employee = viewModel.employees[indexPath.row]
|
|
||||||
let details = EmployeeDetailViewController()
|
|
||||||
details.viewModel = .init(employee: employee)
|
|
||||||
navigationController?.pushViewController(details, animated: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark: - Objective-C Methods
|
// Mark: - Objective-C Methods
|
||||||
extension EmployeesViewController {
|
extension EmployeesViewController {
|
||||||
|
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
//
|
|
||||||
// EmployeeDetailsViewModel.swift
|
|
||||||
// EmployeeDirectory
|
|
||||||
//
|
|
||||||
// Created by Matt Bruce on 2/6/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
/// ViewModel that will be used along with the EmployeeTableViewCell.
|
|
||||||
@MainActor
|
|
||||||
public class EmployeeDetailViewModel: ObservableObject {
|
|
||||||
// MARK: - Properties
|
|
||||||
|
|
||||||
private let employee: Employee
|
|
||||||
|
|
||||||
public private(set) var uuid: String
|
|
||||||
public private(set) var fullName: String
|
|
||||||
public private(set) var phoneNumber: String?
|
|
||||||
public private(set) var emailAddress: String
|
|
||||||
public private(set) var biography: String?
|
|
||||||
public private(set) var team: String
|
|
||||||
public private(set) var employeeType: String
|
|
||||||
@Published public private(set) var largePhoto: UIImage?
|
|
||||||
|
|
||||||
// MARK: - Initializer
|
|
||||||
|
|
||||||
public init(employee: Employee) {
|
|
||||||
self.employee = employee
|
|
||||||
|
|
||||||
// Initialize properties
|
|
||||||
uuid = employee.uuid.uuidString
|
|
||||||
fullName = employee.fullName
|
|
||||||
phoneNumber = employee.phoneNumber?.formatUSNumber()
|
|
||||||
emailAddress = employee.emailAddress
|
|
||||||
biography = employee.biography
|
|
||||||
team = employee.team
|
|
||||||
employeeType = employee.employeeType.description
|
|
||||||
|
|
||||||
// Fetch the image for the url if it exists
|
|
||||||
if let endpoint = employee.photoURLLarge {
|
|
||||||
Task{
|
|
||||||
if let photoURL = URL(string: endpoint) {
|
|
||||||
largePhoto = await ImageCacheService.shared.loadImage(from: photoURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user