// // SertifikatBelumUploadCell.swift // Sirani // // Created by Anhar Solehudin on 16/04/19. // Copyright © 2019 Anhar Solehudin. All rights reserved. // import UIKit import MaterialComponents.MaterialCards protocol SertifikatBelumUploadCellDelegate: NSObjectProtocol { func download(urlWeb: String?, filename: String?) func upload(aplikasiId: Int?) } class SertifikatBelumUploadCell: UITableViewCell { @IBOutlet weak var card: MDCCard! @IBOutlet weak var lblAplikasiId: UILabel! @IBOutlet weak var lblNo: UILabel! @IBOutlet weak var lblTgl: UILabel! @IBOutlet weak var lblPlgId: UILabel! @IBOutlet weak var lblNib: UILabel! @IBOutlet weak var lblCustName: UILabel! @IBOutlet weak var lblEqpName: UILabel! @IBOutlet weak var lblMerk: UILabel! @IBOutlet weak var lblModel: UILabel! @IBOutlet weak var lblBrand: UILabel! @IBOutlet weak var lblPeringatan1: UILabel! @IBOutlet weak var lblPeringatan2: UILabel! @IBOutlet weak var lblPeringatan3: UILabel! @IBOutlet weak var btnUpload: UIButton! @IBOutlet weak var btnDownloadSpt: UIButton! @IBOutlet weak var btnDownloadSt2: UIButton! @IBOutlet weak var btnDownloadSt1: UIButton! var cellDelegate: SertifikatBelumUploadCellDelegate? var aplikasiId = 0 var urlCetakSt1 = "" var urlCetakSt2 = "" var urlCetakSpt = "" // 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 modernStatusPill = UIView() private let modernStatusLabel = UILabel() private let modernPerangkatLabel = UILabel() private let modernCompanyIcon = UIImageView() private let modernCustLabel = UILabel() private let modernSpecStack = UIStackView() private let modernMerkCard = UIView() private let modernMerkTitle = UILabel() private let modernMerkVal = UILabel() private let modernNibCard = UIView() private let modernNibTitle = UILabel() private let modernNibVal = UILabel() private let modernPeringatanCard = UIView() private let modernPeringatanIcon = UIImageView() private let modernPeringatanLabel = UILabel() private let modernValidityCard = UIView() private let modernCalendarIcon = UIImageView() private let modernValidityLabel = UILabel() private let modernAplIdLabel = UILabel() private let modernUploadBtn = UIButton(type: .system) private let modernDownloadStack = UIStackView() private let modernBtnSt1 = UIButton(type: .system) private let modernBtnSt2 = UIButton(type: .system) private let modernBtnSpt = UIButton(type: .system) 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: 254/255, green: 243/255, blue: 199/255, alpha: 1.0) modernBadgeView.layer.cornerRadius = 8 modernBadgeView.layer.masksToBounds = true modernBadgeIcon.translatesAutoresizingMaskIntoConstraints = false if #available(iOS 13.0, *) { modernBadgeIcon.image = UIImage(systemName: "photo") } modernBadgeIcon.tintColor = UIColor(red: 180/255, green: 83/255, blue: 9/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: 180/255, green: 83/255, blue: 9/255, alpha: 1.0) modernCategoryLabel.text = "FOTO LABEL" 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) modernStatusPill.translatesAutoresizingMaskIntoConstraints = false modernStatusPill.layer.cornerRadius = 12 modernStatusPill.layer.masksToBounds = true modernStatusPill.backgroundColor = UIColor(red: 254/255, green: 243/255, blue: 199/255, alpha: 1.0) let statusDot = UIView() statusDot.translatesAutoresizingMaskIntoConstraints = false statusDot.layer.cornerRadius = 3.5 statusDot.backgroundColor = UIColor(red: 245/255, green: 158/255, blue: 11/255, alpha: 1.0) modernStatusLabel.translatesAutoresizingMaskIntoConstraints = false modernStatusLabel.font = UIFont.systemFont(ofSize: 11, weight: .bold) modernStatusLabel.textColor = UIColor(red: 180/255, green: 83/255, blue: 9/255, alpha: 1.0) modernStatusLabel.text = "BELUM UPLOAD" let pillStack = UIStackView(arrangedSubviews: [statusDot, modernStatusLabel]) pillStack.translatesAutoresizingMaskIntoConstraints = false pillStack.axis = .horizontal pillStack.spacing = 5 pillStack.alignment = .center modernStatusPill.addSubview(pillStack) headerStack.addArrangedSubview(modernBadgeView) headerStack.addArrangedSubview(titleStack) headerStack.addArrangedSubview(modernStatusPill) // 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 (Merk/Model/Brand | NIB/PLG) 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(modernMerkCard, titleLabel: modernMerkTitle, valLabel: modernMerkVal, title: "MERK / MODEL / BRAND") styleMiniCard(modernNibCard, titleLabel: modernNibTitle, valLabel: modernNibVal, title: "NIB & ID PELANGGAN") modernSpecStack.addArrangedSubview(modernMerkCard) modernSpecStack.addArrangedSubview(modernNibCard) // 5. Peringatan Box (Optional warning) modernPeringatanCard.translatesAutoresizingMaskIntoConstraints = false modernPeringatanCard.backgroundColor = UIColor(red: 255/255, green: 251/255, blue: 235/255, alpha: 1.0) modernPeringatanCard.layer.cornerRadius = 8 modernPeringatanCard.layer.borderColor = UIColor(red: 253/255, green: 230/255, blue: 138/255, alpha: 1.0).cgColor modernPeringatanCard.layer.borderWidth = 1 modernContainer.addSubview(modernPeringatanCard) modernPeringatanIcon.translatesAutoresizingMaskIntoConstraints = false if #available(iOS 13.0, *) { modernPeringatanIcon.image = UIImage(systemName: "exclamationmark.circle.fill") } modernPeringatanIcon.tintColor = UIColor(red: 217/255, green: 119/255, blue: 6/255, alpha: 1.0) modernPeringatanIcon.contentMode = .scaleAspectFit modernPeringatanLabel.translatesAutoresizingMaskIntoConstraints = false modernPeringatanLabel.font = UIFont.systemFont(ofSize: 11, weight: .medium) modernPeringatanLabel.textColor = UIColor(red: 146/255, green: 64/255, blue: 14/255, alpha: 1.0) modernPeringatanLabel.numberOfLines = 0 let peringatanContent = UIStackView(arrangedSubviews: [modernPeringatanIcon, modernPeringatanLabel]) peringatanContent.translatesAutoresizingMaskIntoConstraints = false peringatanContent.axis = .horizontal peringatanContent.spacing = 8 peringatanContent.alignment = .top modernPeringatanCard.addSubview(peringatanContent) // 6. Validity Footer Bar modernValidityCard.translatesAutoresizingMaskIntoConstraints = false modernValidityCard.backgroundColor = UIColor(red: 244/255, green: 248/255, blue: 254/255, alpha: 1.0) modernValidityCard.layer.cornerRadius = 10 modernContainer.addSubview(modernValidityCard) 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 modernValidityLabel.translatesAutoresizingMaskIntoConstraints = false modernValidityLabel.font = UIFont.systemFont(ofSize: 11, weight: .medium) modernValidityLabel.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 validityContentStack = UIStackView(arrangedSubviews: [modernCalendarIcon, modernValidityLabel]) validityContentStack.translatesAutoresizingMaskIntoConstraints = false validityContentStack.axis = .horizontal validityContentStack.spacing = 6 validityContentStack.alignment = .center let footerStack = UIStackView(arrangedSubviews: [validityContentStack, modernAplIdLabel]) footerStack.translatesAutoresizingMaskIntoConstraints = false footerStack.axis = .horizontal footerStack.distribution = .equalSpacing footerStack.alignment = .center modernValidityCard.addSubview(footerStack) // 7. Primary Action: Upload Button modernUploadBtn.translatesAutoresizingMaskIntoConstraints = false modernUploadBtn.setTitle(" Upload Foto Label", for: .normal) if #available(iOS 13.0, *) { modernUploadBtn.setImage(UIImage(systemName: "camera.fill"), for: .normal) } modernUploadBtn.tintColor = .white modernUploadBtn.setTitleColor(.white, for: .normal) modernUploadBtn.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: .bold) modernUploadBtn.backgroundColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0) modernUploadBtn.layer.cornerRadius = 10 modernUploadBtn.heightAnchor.constraint(equalToConstant: 38).isActive = true modernUploadBtn.addTarget(self, action: #selector(onModernUploadTap), for: .touchUpInside) modernContainer.addSubview(modernUploadBtn) // 8. Download Buttons Stack (ST1, ST2, SPT) modernDownloadStack.translatesAutoresizingMaskIntoConstraints = false modernDownloadStack.axis = .horizontal modernDownloadStack.distribution = .fillEqually modernDownloadStack.spacing = 8 modernContainer.addSubview(modernDownloadStack) func styleDownloadBtn(_ button: UIButton, title: String, action: Selector) { button.translatesAutoresizingMaskIntoConstraints = false button.setTitle(" \(title)", for: .normal) if #available(iOS 13.0, *) { button.setImage(UIImage(systemName: "arrow.down.doc"), for: .normal) } button.tintColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0) button.titleLabel?.font = UIFont.systemFont(ofSize: 11, weight: .semibold) button.backgroundColor = UIColor(red: 244/255, green: 248/255, blue: 254/255, alpha: 1.0) button.layer.cornerRadius = 8 button.layer.borderWidth = 1 button.layer.borderColor = UIColor(red: 218/255, green: 230/255, blue: 247/255, alpha: 1.0).cgColor button.heightAnchor.constraint(equalToConstant: 34).isActive = true button.addTarget(self, action: action, for: .touchUpInside) } styleDownloadBtn(modernBtnSt1, title: "ST1", action: #selector(onModernSt1Tap)) styleDownloadBtn(modernBtnSt2, title: "ST2", action: #selector(onModernSt2Tap)) styleDownloadBtn(modernBtnSpt, title: "SPT", action: #selector(onModernSptTap)) modernDownloadStack.addArrangedSubview(modernBtnSt1) modernDownloadStack.addArrangedSubview(modernBtnSt2) modernDownloadStack.addArrangedSubview(modernBtnSpt) // 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), statusDot.widthAnchor.constraint(equalToConstant: 7), statusDot.heightAnchor.constraint(equalToConstant: 7), pillStack.topAnchor.constraint(equalTo: modernStatusPill.topAnchor, constant: 5), pillStack.bottomAnchor.constraint(equalTo: modernStatusPill.bottomAnchor, constant: -5), pillStack.leadingAnchor.constraint(equalTo: modernStatusPill.leadingAnchor, constant: 10), pillStack.trailingAnchor.constraint(equalTo: modernStatusPill.trailingAnchor, constant: -10), 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), modernPeringatanCard.topAnchor.constraint(equalTo: modernSpecStack.bottomAnchor, constant: 8), modernPeringatanCard.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor), modernPeringatanCard.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor), modernPeringatanIcon.widthAnchor.constraint(equalToConstant: 14), modernPeringatanIcon.heightAnchor.constraint(equalToConstant: 14), peringatanContent.topAnchor.constraint(equalTo: modernPeringatanCard.topAnchor, constant: 8), peringatanContent.bottomAnchor.constraint(equalTo: modernPeringatanCard.bottomAnchor, constant: -8), peringatanContent.leadingAnchor.constraint(equalTo: modernPeringatanCard.leadingAnchor, constant: 8), peringatanContent.trailingAnchor.constraint(equalTo: modernPeringatanCard.trailingAnchor, constant: -8), modernValidityCard.topAnchor.constraint(equalTo: modernPeringatanCard.bottomAnchor, constant: 8), modernValidityCard.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor), modernValidityCard.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor), modernCalendarIcon.widthAnchor.constraint(equalToConstant: 13), modernCalendarIcon.heightAnchor.constraint(equalToConstant: 13), footerStack.topAnchor.constraint(equalTo: modernValidityCard.topAnchor, constant: 8), footerStack.bottomAnchor.constraint(equalTo: modernValidityCard.bottomAnchor, constant: -8), footerStack.leadingAnchor.constraint(equalTo: modernValidityCard.leadingAnchor, constant: 10), footerStack.trailingAnchor.constraint(equalTo: modernValidityCard.trailingAnchor, constant: -10), modernUploadBtn.topAnchor.constraint(equalTo: modernValidityCard.bottomAnchor, constant: 10), modernUploadBtn.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor), modernUploadBtn.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor), modernDownloadStack.topAnchor.constraint(equalTo: modernUploadBtn.bottomAnchor, constant: 8), modernDownloadStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor), modernDownloadStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor), modernDownloadStack.bottomAnchor.constraint(equalTo: modernContainer.bottomAnchor) ]) } @objc private func onModernUploadTap() { cellDelegate?.upload(aplikasiId: aplikasiId) } @objc private func onModernSt1Tap() { let filename = "ST1-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSt1, filename: filename) } @objc private func onModernSt2Tap() { let filename = "ST2-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSt2, filename: filename) } @objc private func onModernSptTap() { let filename = "SPT-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSpt, filename: filename) } func updateViews(sertBlmUpload: SertifikatBelumUpload) { card?.isInteractable = false setupModernLayout() aplikasiId = sertBlmUpload.apl_id urlCetakSt1 = sertBlmUpload.cetak_st1 urlCetakSt2 = sertBlmUpload.cetak_st2 urlCetakSpt = sertBlmUpload.cetak_spt let nomor = sertBlmUpload.nomor.isEmpty ? "-" : sertBlmUpload.nomor modernNomorLabel.text = nomor lblNo?.text = nomor let tglFormatted = CommonHelper.formatDate(from: sertBlmUpload.tgl) let expFormatted = CommonHelper.formatDate(from: sertBlmUpload.exp) modernValidityLabel.text = "\(tglFormatted) s/d \(expFormatted)" lblTgl?.text = "\(tglFormatted) s/d \(expFormatted)" let plgId = "\(sertBlmUpload.plg_id)" let nib = sertBlmUpload.nib.isEmpty ? "-" : sertBlmUpload.nib lblPlgId?.text = "PLG ID: \(plgId)" lblNib?.text = "NIB: \(nib)" modernNibVal.text = "NIB: \(nib) | PLG: \(plgId)" let cust = sertBlmUpload.cust_name.isEmpty ? "-" : sertBlmUpload.cust_name modernCustLabel.text = cust lblCustName?.text = cust let eqp = sertBlmUpload.eqp_name.isEmpty ? "-" : sertBlmUpload.eqp_name modernPerangkatLabel.text = eqp lblEqpName?.text = eqp let merk = sertBlmUpload.merk.isEmpty ? "-" : sertBlmUpload.merk let model = sertBlmUpload.model.isEmpty ? "-" : sertBlmUpload.model let brand = sertBlmUpload.brand.isEmpty ? "-" : sertBlmUpload.brand lblMerk?.text = "Merk: \(merk)" lblModel?.text = "Model: \(model)" lblBrand?.text = "Brand: \(brand)" modernMerkVal.text = "\(merk) / \(model) / \(brand)" modernAplIdLabel.text = "ID: \(sertBlmUpload.apl_id)" lblAplikasiId?.text = "\(sertBlmUpload.apl_id)" // Peringatan handling var peringatanText = "" if let p1 = sertBlmUpload.peringatan_pertama, !p1.isEmpty { peringatanText = "Peringatan 1: \(p1)" lblPeringatan1?.text = peringatanText } if let p2 = sertBlmUpload.peringatan_kedua, !p2.isEmpty { peringatanText += (peringatanText.isEmpty ? "" : "\n") + "Peringatan 2: \(p2)" lblPeringatan2?.text = "Peringatan 2: \(p2)" } if let p3 = sertBlmUpload.peringatan_ketiga, !p3.isEmpty { peringatanText += (peringatanText.isEmpty ? "" : "\n") + "Peringatan 3: \(p3)" lblPeringatan3?.text = "Peringatan 3: \(p3)" } if peringatanText.isEmpty { modernPeringatanCard.isHidden = true } else { modernPeringatanCard.isHidden = false modernPeringatanLabel.text = peringatanText } // Button state check modernBtnSt1.alpha = urlCetakSt1.isEmpty ? 0.4 : 1.0 modernBtnSt2.alpha = urlCetakSt2.isEmpty ? 0.4 : 1.0 modernBtnSpt.alpha = urlCetakSpt.isEmpty ? 0.4 : 1.0 } @IBAction func onBtnUploadTap(_ sender: Any) { cellDelegate?.upload(aplikasiId: aplikasiId) } @IBAction func onBtnDownloadSt1Tap(_ sender: Any) { let filename = "ST1-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSt1, filename: filename) } @IBAction func onBtnDownloadSt2Tap(_ sender: Any) { let filename = "ST2-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSt2, filename: filename) } @IBAction func onBtnDownloadSptTap(_ sender: Any) { let filename = "SPT-\(aplikasiId).jpg" cellDelegate?.download(urlWeb: urlCetakSpt, filename: filename) } }