| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- //
- // Sp2SertifikatCell.swift
- // Sirani
- //
- // Created by Anhar Solehudin on 27/04/19.
- // Copyright © 2019 Anhar Solehudin. All rights reserved.
- //
- import UIKit
- import MaterialComponents.MaterialCards
- class Sp2SertifikatCell: UITableViewCell {
-
- @IBOutlet weak var card: MDCCard!
- @IBOutlet weak var lblAplId: UILabel!
- @IBOutlet weak var lblNo: UILabel!
- @IBOutlet weak var lblTgl: UILabel!
- @IBOutlet weak var lblCustName: UILabel!
- @IBOutlet weak var lblEqpName: UILabel!
- @IBOutlet weak var lblModels: UILabel!
- @IBOutlet weak var lblBiaya: UILabel!
- @IBOutlet weak var cbKasi: UIImageView!
- @IBOutlet weak var cbKasub: UIImageView!
- @IBOutlet weak var cbDirektur: UIImageView!
-
- // Modern Programmatic UI Elements
- private let modernContainer = UIView()
- private let modernBadgeView = UIView()
- private let modernBadgeIcon = UIImageView()
- private let modernNomorLabel = UILabel()
- private let modernCategoryLabel = UILabel()
- private let modernBiayaPill = UIView()
- private let modernBiayaLabel = UILabel()
-
- private let modernPerangkatLabel = UILabel()
- private let modernCompanyIcon = UIImageView()
- private let modernCustLabel = UILabel()
-
- private let modernSpecStack = UIStackView()
- private let modernModelCard = UIView()
- private let modernModelTitle = UILabel()
- private let modernModelVal = UILabel()
-
- private let modernBiayaCard = UIView()
- private let modernBiayaTitle = UILabel()
- private let modernBiayaVal = UILabel()
-
- private let modernApprovalStack = UIStackView()
- private let modernKasiBadge = UIView()
- private let modernKasiLabel = UILabel()
- private let modernKasubBadge = UIView()
- private let modernKasubLabel = UILabel()
- private let modernDirutBadge = UIView()
- private let modernDirutLabel = UILabel()
-
- private let modernFooterCard = UIView()
- private let modernCalendarIcon = UIImageView()
- private let modernDateLabel = UILabel()
- private let modernAplIdLabel = UILabel()
-
- private var isModernLayoutBuilt = false
- override func awakeFromNib() {
- super.awakeFromNib()
-
- self.selectionStyle = .none
- self.backgroundColor = .clear
-
- setupCardVisuals()
- setupModernLayout()
- }
-
- private func setupCardVisuals() {
- guard let card = card else { return }
- card.cornerRadius = 16
- card.setShadowElevation(ShadowElevation(rawValue: 2), for: .normal)
- card.setShadowColor(UIColor.black.withAlphaComponent(0.06), for: .normal)
- card.layer.borderColor = UIColor(red: 228/255, green: 235/255, blue: 245/255, alpha: 1.0).cgColor
- card.layer.borderWidth = 1.0
- card.backgroundColor = .white
- }
-
- private func setupModernLayout() {
- guard let card = card, !isModernLayoutBuilt else { return }
- isModernLayoutBuilt = true
-
- for subview in card.subviews {
- subview.isHidden = true
- }
-
- modernContainer.translatesAutoresizingMaskIntoConstraints = false
- modernContainer.backgroundColor = .clear
- card.addSubview(modernContainer)
-
- NSLayoutConstraint.activate([
- modernContainer.topAnchor.constraint(equalTo: card.topAnchor, constant: 14),
- modernContainer.bottomAnchor.constraint(equalTo: card.bottomAnchor, constant: -14),
- modernContainer.leadingAnchor.constraint(equalTo: card.leadingAnchor, constant: 14),
- modernContainer.trailingAnchor.constraint(equalTo: card.trailingAnchor, constant: -14)
- ])
-
- // 1. Header Bar
- let headerStack = UIStackView()
- headerStack.translatesAutoresizingMaskIntoConstraints = false
- headerStack.axis = .horizontal
- headerStack.alignment = .center
- headerStack.spacing = 10
- modernContainer.addSubview(headerStack)
-
- modernBadgeView.translatesAutoresizingMaskIntoConstraints = false
- modernBadgeView.backgroundColor = UIColor(red: 235/255, green: 242/255, blue: 252/255, alpha: 1.0)
- modernBadgeView.layer.cornerRadius = 8
- modernBadgeView.layer.masksToBounds = true
-
- modernBadgeIcon.translatesAutoresizingMaskIntoConstraints = false
- if #available(iOS 13.0, *) {
- modernBadgeIcon.image = UIImage(systemName: "doc.plaintext.fill")
- }
- modernBadgeIcon.tintColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
- modernBadgeIcon.contentMode = .scaleAspectFit
- modernBadgeView.addSubview(modernBadgeIcon)
-
- let titleStack = UIStackView()
- titleStack.translatesAutoresizingMaskIntoConstraints = false
- titleStack.axis = .vertical
- titleStack.spacing = 2
-
- modernCategoryLabel.translatesAutoresizingMaskIntoConstraints = false
- modernCategoryLabel.font = UIFont.systemFont(ofSize: 10, weight: .bold)
- modernCategoryLabel.textColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
- modernCategoryLabel.text = "SP2 SERTIFIKAT"
-
- modernNomorLabel.translatesAutoresizingMaskIntoConstraints = false
- modernNomorLabel.font = UIFont.systemFont(ofSize: 14, weight: .bold)
- modernNomorLabel.textColor = UIColor(red: 26/255, green: 32/255, blue: 44/255, alpha: 1.0)
- modernNomorLabel.numberOfLines = 1
-
- titleStack.addArrangedSubview(modernCategoryLabel)
- titleStack.addArrangedSubview(modernNomorLabel)
-
- modernBiayaPill.translatesAutoresizingMaskIntoConstraints = false
- modernBiayaPill.layer.cornerRadius = 12
- modernBiayaPill.layer.masksToBounds = true
- modernBiayaPill.backgroundColor = UIColor(red: 235/255, green: 242/255, blue: 252/255, alpha: 1.0)
-
- modernBiayaLabel.translatesAutoresizingMaskIntoConstraints = false
- modernBiayaLabel.font = UIFont.systemFont(ofSize: 11, weight: .bold)
- modernBiayaLabel.textColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
- modernBiayaPill.addSubview(modernBiayaLabel)
-
- NSLayoutConstraint.activate([
- modernBiayaLabel.topAnchor.constraint(equalTo: modernBiayaPill.topAnchor, constant: 5),
- modernBiayaLabel.bottomAnchor.constraint(equalTo: modernBiayaPill.bottomAnchor, constant: -5),
- modernBiayaLabel.leadingAnchor.constraint(equalTo: modernBiayaPill.leadingAnchor, constant: 10),
- modernBiayaLabel.trailingAnchor.constraint(equalTo: modernBiayaPill.trailingAnchor, constant: -10)
- ])
-
- headerStack.addArrangedSubview(modernBadgeView)
- headerStack.addArrangedSubview(titleStack)
- headerStack.addArrangedSubview(modernBiayaPill)
-
- // 2. Equipment Name
- modernPerangkatLabel.translatesAutoresizingMaskIntoConstraints = false
- modernPerangkatLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold)
- modernPerangkatLabel.textColor = UIColor(red: 26/255, green: 32/255, blue: 44/255, alpha: 1.0)
- modernPerangkatLabel.numberOfLines = 2
- modernContainer.addSubview(modernPerangkatLabel)
-
- // 3. Company Row
- let companyStack = UIStackView()
- companyStack.translatesAutoresizingMaskIntoConstraints = false
- companyStack.axis = .horizontal
- companyStack.spacing = 6
- companyStack.alignment = .center
- modernContainer.addSubview(companyStack)
-
- modernCompanyIcon.translatesAutoresizingMaskIntoConstraints = false
- if #available(iOS 13.0, *) {
- modernCompanyIcon.image = UIImage(systemName: "building.2.fill")
- }
- modernCompanyIcon.tintColor = UIColor(red: 113/255, green: 128/255, blue: 150/255, alpha: 1.0)
- modernCompanyIcon.contentMode = .scaleAspectFit
-
- modernCustLabel.translatesAutoresizingMaskIntoConstraints = false
- modernCustLabel.font = UIFont.systemFont(ofSize: 13, weight: .medium)
- modernCustLabel.textColor = UIColor(red: 74/255, green: 85/255, blue: 104/255, alpha: 1.0)
- modernCustLabel.numberOfLines = 1
-
- companyStack.addArrangedSubview(modernCompanyIcon)
- companyStack.addArrangedSubview(modernCustLabel)
-
- // 4. Spec Stack (Model | Biaya)
- modernSpecStack.translatesAutoresizingMaskIntoConstraints = false
- modernSpecStack.axis = .horizontal
- modernSpecStack.distribution = .fillEqually
- modernSpecStack.spacing = 8
- modernContainer.addSubview(modernSpecStack)
-
- func styleMiniCard(_ cardView: UIView, titleLabel: UILabel, valLabel: UILabel, title: String) {
- cardView.translatesAutoresizingMaskIntoConstraints = false
- cardView.backgroundColor = UIColor(red: 248/255, green: 250/255, blue: 253/255, alpha: 1.0)
- cardView.layer.cornerRadius = 8
- cardView.layer.borderColor = UIColor(red: 235/255, green: 240/255, blue: 248/255, alpha: 1.0).cgColor
- cardView.layer.borderWidth = 1
-
- titleLabel.translatesAutoresizingMaskIntoConstraints = false
- titleLabel.font = UIFont.systemFont(ofSize: 10, weight: .semibold)
- titleLabel.textColor = UIColor(red: 113/255, green: 128/255, blue: 150/255, alpha: 1.0)
- titleLabel.text = title
-
- valLabel.translatesAutoresizingMaskIntoConstraints = false
- valLabel.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
- valLabel.textColor = UIColor(red: 45/255, green: 55/255, blue: 72/255, alpha: 1.0)
- valLabel.numberOfLines = 1
-
- let stack = UIStackView(arrangedSubviews: [titleLabel, valLabel])
- stack.translatesAutoresizingMaskIntoConstraints = false
- stack.axis = .vertical
- stack.spacing = 2
- cardView.addSubview(stack)
-
- NSLayoutConstraint.activate([
- stack.topAnchor.constraint(equalTo: cardView.topAnchor, constant: 6),
- stack.bottomAnchor.constraint(equalTo: cardView.bottomAnchor, constant: -6),
- stack.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 8),
- stack.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -8)
- ])
- }
-
- styleMiniCard(modernModelCard, titleLabel: modernModelTitle, valLabel: modernModelVal, title: "MODEL")
- styleMiniCard(modernBiayaCard, titleLabel: modernBiayaTitle, valLabel: modernBiayaVal, title: "TOTAL BIAYA")
-
- modernSpecStack.addArrangedSubview(modernModelCard)
- modernSpecStack.addArrangedSubview(modernBiayaCard)
-
- // 5. Approval Flow Badges (Kasi, Kasub, Direktur)
- modernApprovalStack.translatesAutoresizingMaskIntoConstraints = false
- modernApprovalStack.axis = .horizontal
- modernApprovalStack.distribution = .fillEqually
- modernApprovalStack.spacing = 6
- modernContainer.addSubview(modernApprovalStack)
-
- func createStepBadge(_ container: UIView, label: UILabel, role: String) {
- container.translatesAutoresizingMaskIntoConstraints = false
- container.layer.cornerRadius = 6
- container.layer.masksToBounds = true
-
- label.translatesAutoresizingMaskIntoConstraints = false
- label.font = UIFont.systemFont(ofSize: 10, weight: .bold)
- label.textAlignment = .center
- label.text = role
- container.addSubview(label)
-
- NSLayoutConstraint.activate([
- label.topAnchor.constraint(equalTo: container.topAnchor, constant: 4),
- label.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -4),
- label.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 4),
- label.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -4)
- ])
- }
-
- createStepBadge(modernKasiBadge, label: modernKasiLabel, role: "Kasi")
- createStepBadge(modernKasubBadge, label: modernKasubLabel, role: "Kasub")
- createStepBadge(modernDirutBadge, label: modernDirutLabel, role: "Direktur")
-
- modernApprovalStack.addArrangedSubview(modernKasiBadge)
- modernApprovalStack.addArrangedSubview(modernKasubBadge)
- modernApprovalStack.addArrangedSubview(modernDirutBadge)
-
- // 6. Footer Bar
- modernFooterCard.translatesAutoresizingMaskIntoConstraints = false
- modernFooterCard.backgroundColor = UIColor(red: 244/255, green: 248/255, blue: 254/255, alpha: 1.0)
- modernFooterCard.layer.cornerRadius = 10
- modernContainer.addSubview(modernFooterCard)
-
- modernCalendarIcon.translatesAutoresizingMaskIntoConstraints = false
- if #available(iOS 13.0, *) {
- modernCalendarIcon.image = UIImage(systemName: "calendar")
- }
- modernCalendarIcon.tintColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
- modernCalendarIcon.contentMode = .scaleAspectFit
-
- modernDateLabel.translatesAutoresizingMaskIntoConstraints = false
- modernDateLabel.font = UIFont.systemFont(ofSize: 11, weight: .medium)
- modernDateLabel.textColor = UIColor(red: 74/255, green: 85/255, blue: 104/255, alpha: 1.0)
-
- modernAplIdLabel.translatesAutoresizingMaskIntoConstraints = false
- modernAplIdLabel.font = UIFont.systemFont(ofSize: 10, weight: .bold)
- modernAplIdLabel.textColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
-
- let dateContentStack = UIStackView(arrangedSubviews: [modernCalendarIcon, modernDateLabel])
- dateContentStack.translatesAutoresizingMaskIntoConstraints = false
- dateContentStack.axis = .horizontal
- dateContentStack.spacing = 6
- dateContentStack.alignment = .center
-
- let footerStack = UIStackView(arrangedSubviews: [dateContentStack, modernAplIdLabel])
- footerStack.translatesAutoresizingMaskIntoConstraints = false
- footerStack.axis = .horizontal
- footerStack.distribution = .equalSpacing
- footerStack.alignment = .center
- modernFooterCard.addSubview(footerStack)
-
- // Constraints
- NSLayoutConstraint.activate([
- headerStack.topAnchor.constraint(equalTo: modernContainer.topAnchor),
- headerStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- headerStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
-
- modernBadgeView.widthAnchor.constraint(equalToConstant: 34),
- modernBadgeView.heightAnchor.constraint(equalToConstant: 34),
- modernBadgeIcon.centerXAnchor.constraint(equalTo: modernBadgeView.centerXAnchor),
- modernBadgeIcon.centerYAnchor.constraint(equalTo: modernBadgeView.centerYAnchor),
- modernBadgeIcon.widthAnchor.constraint(equalToConstant: 18),
- modernBadgeIcon.heightAnchor.constraint(equalToConstant: 18),
-
- modernPerangkatLabel.topAnchor.constraint(equalTo: headerStack.bottomAnchor, constant: 10),
- modernPerangkatLabel.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- modernPerangkatLabel.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
-
- companyStack.topAnchor.constraint(equalTo: modernPerangkatLabel.bottomAnchor, constant: 6),
- companyStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- companyStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
- modernCompanyIcon.widthAnchor.constraint(equalToConstant: 14),
- modernCompanyIcon.heightAnchor.constraint(equalToConstant: 14),
-
- modernSpecStack.topAnchor.constraint(equalTo: companyStack.bottomAnchor, constant: 10),
- modernSpecStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- modernSpecStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
-
- modernApprovalStack.topAnchor.constraint(equalTo: modernSpecStack.bottomAnchor, constant: 10),
- modernApprovalStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- modernApprovalStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
-
- modernFooterCard.topAnchor.constraint(equalTo: modernApprovalStack.bottomAnchor, constant: 10),
- modernFooterCard.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
- modernFooterCard.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
- modernFooterCard.bottomAnchor.constraint(equalTo: modernContainer.bottomAnchor),
-
- modernCalendarIcon.widthAnchor.constraint(equalToConstant: 13),
- modernCalendarIcon.heightAnchor.constraint(equalToConstant: 13),
-
- footerStack.topAnchor.constraint(equalTo: modernFooterCard.topAnchor, constant: 8),
- footerStack.bottomAnchor.constraint(equalTo: modernFooterCard.bottomAnchor, constant: -8),
- footerStack.leadingAnchor.constraint(equalTo: modernFooterCard.leadingAnchor, constant: 10),
- footerStack.trailingAnchor.constraint(equalTo: modernFooterCard.trailingAnchor, constant: -10)
- ])
- }
-
- private func updateBadgeState(_ container: UIView, label: UILabel, role: String, approved: Bool) {
- if approved {
- container.backgroundColor = UIColor(red: 232/255, green: 248/255, blue: 240/255, alpha: 1.0)
- label.textColor = UIColor(red: 16/255, green: 124/255, blue: 65/255, alpha: 1.0)
- label.text = "✓ \(role)"
- } else {
- container.backgroundColor = UIColor(red: 241/255, green: 245/255, blue: 249/255, alpha: 1.0)
- label.textColor = UIColor(red: 148/255, green: 163/255, blue: 184/255, alpha: 1.0)
- label.text = "○ \(role)"
- }
- }
- func updateViews(sp2Sertifikat: Sp2Sertifikat) {
- card?.isInteractable = false
- setupModernLayout()
-
- modernAplIdLabel.text = "ID: \(sp2Sertifikat.apl_id)"
- lblAplId?.text = "\(sp2Sertifikat.apl_id)"
-
- let sp2No = sp2Sertifikat.sp2_no.isEmpty ? "-" : sp2Sertifikat.sp2_no
- modernNomorLabel.text = sp2No
- lblNo?.text = sp2No
-
- let datePrefix = String(sp2Sertifikat.sp2_date.prefix(19))
- let dateFormatted = CommonHelper.formatDate(from: datePrefix)
- modernDateLabel.text = "Tanggal: \(dateFormatted)"
- lblTgl?.text = dateFormatted
-
- let cust = sp2Sertifikat.custs.isEmpty ? "-" : sp2Sertifikat.custs
- modernCustLabel.text = cust
- lblCustName?.text = cust
-
- var eqpName = "-"
- var model = "-"
- let eqpValue = sp2Sertifikat.eqp_name
- let values = eqpValue.split(separator: "&")
- if values.count > 0 {
- eqpName = String(values[0]).trimmingCharacters(in: .whitespacesAndNewlines)
- }
- if values.count > 1 {
- model = String(values[1]).trimmingCharacters(in: .whitespacesAndNewlines)
- }
-
- modernPerangkatLabel.text = eqpName
- lblEqpName?.text = eqpName
-
- modernModelVal.text = model
- lblModels?.text = model
-
- let formattedBiaya = formatCurrency(sp2Sertifikat.biaya)
- modernBiayaLabel.text = formattedBiaya
- modernBiayaVal.text = formattedBiaya
- lblBiaya?.text = formattedBiaya
-
- let isKasi = sp2Sertifikat.kasiCetak()
- let isKasub = sp2Sertifikat.kasubCetak()
- let isDirut = sp2Sertifikat.dirutCetak()
-
- updateBadgeState(modernKasiBadge, label: modernKasiLabel, role: "Kasi", approved: isKasi)
- updateBadgeState(modernKasubBadge, label: modernKasubLabel, role: "Kasub", approved: isKasub)
- updateBadgeState(modernDirutBadge, label: modernDirutLabel, role: "Direktur", approved: isDirut)
-
- cbKasi?.image = UIImage(named: isKasi ? "checked-box" : "unchecked-box")
- cbKasub?.image = UIImage(named: isKasub ? "checked-box" : "unchecked-box")
- cbDirektur?.image = UIImage(named: isDirut ? "checked-box" : "unchecked-box")
- }
-
- private func formatCurrency(_ value: String) -> String {
- if let dbl = Double(value) {
- let formatter = NumberFormatter()
- formatter.numberStyle = .currency
- formatter.locale = Locale(identifier: "id_ID")
- formatter.currencySymbol = "Rp "
- formatter.maximumFractionDigits = 0
- if let str = formatter.string(from: NSNumber(value: dbl)) {
- return str
- }
- }
- return value.isEmpty ? "-" : "Rp \(value)"
- }
- }
|