131 lines
5.1 KiB
Swift
131 lines
5.1 KiB
Swift
//
|
|
// EmployeeTableViewCell.swift
|
|
// EmployeeDirectory
|
|
//
|
|
// Created by Matt Bruce on 1/20/25.
|
|
//
|
|
import UIKit
|
|
import Combine
|
|
|
|
public class EmployeeTableViewCell: UITableViewCell {
|
|
static let identifier = "EmployeeTableViewCell"
|
|
|
|
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 var cancellable: AnyCancellable?
|
|
|
|
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
|
setupUI()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
private func setupUI() {
|
|
// Configure photoImageView
|
|
photoImageView.contentMode = .scaleAspectFill
|
|
photoImageView.clipsToBounds = true
|
|
photoImageView.layer.cornerRadius = 25
|
|
photoImageView.translatesAutoresizingMaskIntoConstraints = false
|
|
photoImageView.image = UIImage(systemName: "person.crop.circle")
|
|
|
|
// Configure labels with text styles
|
|
nameLabel.font = UIFont.preferredFont(forTextStyle: .headline) // Bold, prominent text
|
|
nameLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
|
|
|
|
emailLabel.font = UIFont.preferredFont(forTextStyle: .body)
|
|
emailLabel.textColor = .blue
|
|
emailLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
|
|
|
|
teamLabel.font = UIFont.preferredFont(forTextStyle: .subheadline) // Secondary, smaller text
|
|
teamLabel.textColor = .gray
|
|
teamLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
|
|
|
|
employeeTypeLabel.font = UIFont.preferredFont(forTextStyle: .subheadline)
|
|
employeeTypeLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
|
|
|
|
phoneLabel.font = UIFont.preferredFont(forTextStyle: .body) // Standard body text
|
|
phoneLabel.textColor = .darkGray
|
|
phoneLabel.adjustsFontForContentSizeCategory = true// Adapts to Dynamic Type
|
|
|
|
bioLabel.font = UIFont.preferredFont(forTextStyle: .footnote) // Smaller text for additional info
|
|
bioLabel.numberOfLines = 0
|
|
bioLabel.textColor = .lightGray
|
|
bioLabel.adjustsFontForContentSizeCategory = true // Adapts to Dynamic Type
|
|
|
|
// Configure stackView
|
|
stackView.axis = .vertical
|
|
stackView.spacing = 5
|
|
stackView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
// Add labels to stackView
|
|
stackView.addArrangedSubview(nameLabel)
|
|
stackView.addArrangedSubview(teamLabel)
|
|
stackView.addArrangedSubview(employeeTypeLabel)
|
|
stackView.addArrangedSubview(phoneLabel)
|
|
stackView.addArrangedSubview(emailLabel)
|
|
stackView.addArrangedSubview(bioLabel)
|
|
|
|
// Add subviews
|
|
contentView.addSubview(photoImageView)
|
|
contentView.addSubview(stackView)
|
|
|
|
// Add constraints
|
|
NSLayoutConstraint.activate([
|
|
photoImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
|
|
photoImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
|
photoImageView.widthAnchor.constraint(equalToConstant: 50),
|
|
photoImageView.heightAnchor.constraint(equalToConstant: 50),
|
|
|
|
stackView.leadingAnchor.constraint(equalTo: photoImageView.trailingAnchor, constant: 10),
|
|
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
|
|
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
|
|
stackView.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -10)
|
|
])
|
|
}
|
|
|
|
public override func prepareForReuse() {
|
|
super.prepareForReuse()
|
|
cancellable = nil
|
|
photoImageView.image = UIImage(systemName: "person.crop.circle")
|
|
nameLabel.text = nil
|
|
emailLabel.text = nil
|
|
teamLabel.text = nil
|
|
employeeTypeLabel.text = nil
|
|
phoneLabel.text = nil
|
|
bioLabel.text = nil
|
|
}
|
|
|
|
public func configure(with viewModel: EmployeeCellViewModel) {
|
|
|
|
// Bind the image to the photoImageView
|
|
cancellable = viewModel.$smallPhoto
|
|
.receive(on: DispatchQueue.main)
|
|
.sink { [weak self] image in
|
|
self?.photoImageView.image = image
|
|
}
|
|
|
|
// 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
|
|
|
|
}
|
|
}
|