DaftarSertifikatCell.swift 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. //
  2. // DaftarSertifikatCell.swift
  3. // Sirani
  4. //
  5. // Created by Anhar Solehudin on 30/03/19.
  6. // Copyright © 2019 Anhar Solehudin. All rights reserved.
  7. //
  8. import UIKit
  9. import MaterialComponents.MaterialCards
  10. protocol SertifikatCellDelegate: NSObjectProtocol {
  11. func openSertifikatDetail(data: CertificateData?)
  12. }
  13. class DaftarSertifikatCell: UITableViewCell {
  14. @IBOutlet weak var card: MDCCard!
  15. @IBOutlet weak var lblNomor: UILabel!
  16. @IBOutlet weak var lblPlgId: UILabel!
  17. @IBOutlet weak var lblCustomerName: UILabel!
  18. @IBOutlet weak var lblPerangkat: UILabel!
  19. @IBOutlet weak var lblMerk: UILabel!
  20. @IBOutlet weak var lblBrand: UILabel!
  21. @IBOutlet weak var lblExpDate: UILabel!
  22. var cellDelegate: SertifikatCellDelegate?
  23. var dataSertifikat: CertificateData?
  24. // Modern UI
  25. private let modernContainer = UIView()
  26. private let modernBadgeView = UIView()
  27. private let modernBadgeIcon = UIImageView()
  28. private let modernNomorLabel = UILabel()
  29. private let modernCategoryLabel = UILabel()
  30. private let modernStatusPill = UIView()
  31. private let modernStatusLabel = UILabel()
  32. private let modernPerangkatLabel = UILabel()
  33. private let modernCompanyIcon = UIImageView()
  34. private let modernPemohonLabel = UILabel()
  35. private let modernSpecStack = UIStackView()
  36. private let modernMerkCard = UIView()
  37. private let modernMerkTitle = UILabel()
  38. private let modernMerkVal = UILabel()
  39. private let modernPlgCard = UIView()
  40. private let modernPlgTitle = UILabel()
  41. private let modernPlgVal = UILabel()
  42. private let modernValidityCard = UIView()
  43. private let modernCalendarIcon = UIImageView()
  44. private let modernValidityLabel = UILabel()
  45. private let modernDetailLabel = UILabel()
  46. private let modernChevronIcon = UIImageView()
  47. private var isModernLayoutBuilt = false
  48. override func awakeFromNib() {
  49. super.awakeFromNib()
  50. self.selectionStyle = .none
  51. self.backgroundColor = .clear
  52. setupCardVisuals()
  53. setupModernLayout()
  54. }
  55. private func setupCardVisuals() {
  56. guard let card = card else { return }
  57. card.cornerRadius = 16
  58. card.setShadowElevation(ShadowElevation(rawValue: 2), for: .normal)
  59. card.setShadowColor(UIColor.black.withAlphaComponent(0.06), for: .normal)
  60. card.layer.borderColor = UIColor(red: 228/255, green: 235/255, blue: 245/255, alpha: 1.0).cgColor
  61. card.layer.borderWidth = 1.0
  62. card.backgroundColor = .white
  63. }
  64. private func setupModernLayout() {
  65. guard let card = card, !isModernLayoutBuilt else { return }
  66. isModernLayoutBuilt = true
  67. for subview in card.subviews {
  68. subview.isHidden = true
  69. }
  70. modernContainer.translatesAutoresizingMaskIntoConstraints = false
  71. modernContainer.backgroundColor = .clear
  72. card.addSubview(modernContainer)
  73. NSLayoutConstraint.activate([
  74. modernContainer.topAnchor.constraint(equalTo: card.topAnchor, constant: 14),
  75. modernContainer.bottomAnchor.constraint(equalTo: card.bottomAnchor, constant: -14),
  76. modernContainer.leadingAnchor.constraint(equalTo: card.leadingAnchor, constant: 14),
  77. modernContainer.trailingAnchor.constraint(equalTo: card.trailingAnchor, constant: -14)
  78. ])
  79. // 1. Header Bar
  80. let headerStack = UIStackView()
  81. headerStack.translatesAutoresizingMaskIntoConstraints = false
  82. headerStack.axis = .horizontal
  83. headerStack.alignment = .center
  84. headerStack.spacing = 10
  85. modernContainer.addSubview(headerStack)
  86. modernBadgeView.translatesAutoresizingMaskIntoConstraints = false
  87. modernBadgeView.backgroundColor = UIColor(red: 235/255, green: 242/255, blue: 252/255, alpha: 1.0)
  88. modernBadgeView.layer.cornerRadius = 8
  89. modernBadgeView.layer.masksToBounds = true
  90. modernBadgeIcon.translatesAutoresizingMaskIntoConstraints = false
  91. if #available(iOS 13.0, *) {
  92. modernBadgeIcon.image = UIImage(systemName: "checkmark.seal.fill")
  93. }
  94. modernBadgeIcon.tintColor = UIColor.siraniPrimaryBlue
  95. modernBadgeIcon.contentMode = .scaleAspectFit
  96. modernBadgeView.addSubview(modernBadgeIcon)
  97. NSLayoutConstraint.activate([
  98. modernBadgeView.widthAnchor.constraint(equalToConstant: 32),
  99. modernBadgeView.heightAnchor.constraint(equalToConstant: 32),
  100. modernBadgeIcon.centerXAnchor.constraint(equalTo: modernBadgeView.centerXAnchor),
  101. modernBadgeIcon.centerYAnchor.constraint(equalTo: modernBadgeView.centerYAnchor),
  102. modernBadgeIcon.widthAnchor.constraint(equalToConstant: 18),
  103. modernBadgeIcon.heightAnchor.constraint(equalToConstant: 18)
  104. ])
  105. headerStack.addArrangedSubview(modernBadgeView)
  106. let numberStack = UIStackView()
  107. numberStack.axis = .vertical
  108. numberStack.spacing = 1
  109. modernCategoryLabel.font = UIFont.systemFont(ofSize: 9, weight: .bold)
  110. modernCategoryLabel.textColor = UIColor(red: 140/255, green: 155/255, blue: 175/255, alpha: 1.0)
  111. modernCategoryLabel.text = "NOMOR SERTIFIKAT"
  112. numberStack.addArrangedSubview(modernCategoryLabel)
  113. modernNomorLabel.font = UIFont.systemFont(ofSize: 14, weight: .bold)
  114. modernNomorLabel.textColor = UIColor.siraniPrimaryBlue
  115. modernNomorLabel.numberOfLines = 1
  116. modernNomorLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
  117. modernNomorLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
  118. numberStack.addArrangedSubview(modernNomorLabel)
  119. headerStack.addArrangedSubview(numberStack)
  120. // Status Pill
  121. modernStatusPill.translatesAutoresizingMaskIntoConstraints = false
  122. modernStatusPill.layer.cornerRadius = 6
  123. modernStatusPill.layer.masksToBounds = true
  124. modernStatusPill.backgroundColor = UIColor(red: 230/255, green: 244/255, blue: 234/255, alpha: 1.0)
  125. modernStatusLabel.translatesAutoresizingMaskIntoConstraints = false
  126. modernStatusLabel.font = UIFont.systemFont(ofSize: 10, weight: .bold)
  127. modernStatusLabel.textColor = UIColor(red: 19/255, green: 115/255, blue: 51/255, alpha: 1.0)
  128. modernStatusLabel.textAlignment = .center
  129. modernStatusPill.addSubview(modernStatusLabel)
  130. NSLayoutConstraint.activate([
  131. modernStatusLabel.topAnchor.constraint(equalTo: modernStatusPill.topAnchor, constant: 4),
  132. modernStatusLabel.bottomAnchor.constraint(equalTo: modernStatusPill.bottomAnchor, constant: -4),
  133. modernStatusLabel.leadingAnchor.constraint(equalTo: modernStatusPill.leadingAnchor, constant: 8),
  134. modernStatusLabel.trailingAnchor.constraint(equalTo: modernStatusPill.trailingAnchor, constant: -8)
  135. ])
  136. headerStack.addArrangedSubview(modernStatusPill)
  137. // 2. Divider
  138. let divider = UIView()
  139. divider.translatesAutoresizingMaskIntoConstraints = false
  140. divider.backgroundColor = UIColor(red: 240/255, green: 244/255, blue: 250/255, alpha: 1.0)
  141. modernContainer.addSubview(divider)
  142. // 3. Equipment Name
  143. modernPerangkatLabel.translatesAutoresizingMaskIntoConstraints = false
  144. modernPerangkatLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold)
  145. modernPerangkatLabel.textColor = UIColor(red: 26/255, green: 29/255, blue: 38/255, alpha: 1.0)
  146. modernPerangkatLabel.numberOfLines = 2
  147. modernContainer.addSubview(modernPerangkatLabel)
  148. // 4. Company Row
  149. let companyStack = UIStackView()
  150. companyStack.translatesAutoresizingMaskIntoConstraints = false
  151. companyStack.axis = .horizontal
  152. companyStack.spacing = 6
  153. companyStack.alignment = .center
  154. if #available(iOS 13.0, *) {
  155. modernCompanyIcon.image = UIImage(systemName: "building.2.fill")
  156. }
  157. modernCompanyIcon.tintColor = UIColor(red: 120/255, green: 135/255, blue: 155/255, alpha: 1.0)
  158. modernCompanyIcon.contentMode = .scaleAspectFit
  159. modernCompanyIcon.translatesAutoresizingMaskIntoConstraints = false
  160. NSLayoutConstraint.activate([
  161. modernCompanyIcon.widthAnchor.constraint(equalToConstant: 14),
  162. modernCompanyIcon.heightAnchor.constraint(equalToConstant: 14)
  163. ])
  164. companyStack.addArrangedSubview(modernCompanyIcon)
  165. modernPemohonLabel.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
  166. modernPemohonLabel.textColor = UIColor(red: 90/255, green: 105/255, blue: 125/255, alpha: 1.0)
  167. modernPemohonLabel.numberOfLines = 1
  168. companyStack.addArrangedSubview(modernPemohonLabel)
  169. modernContainer.addSubview(companyStack)
  170. // 5. Spec Mini Cards
  171. modernSpecStack.translatesAutoresizingMaskIntoConstraints = false
  172. modernSpecStack.axis = .horizontal
  173. modernSpecStack.distribution = .fillEqually
  174. modernSpecStack.spacing = 8
  175. modernContainer.addSubview(modernSpecStack)
  176. modernMerkCard.backgroundColor = UIColor(red: 248/255, green: 250/255, blue: 253/255, alpha: 1.0)
  177. modernMerkCard.layer.cornerRadius = 8
  178. modernMerkCard.layer.borderWidth = 1
  179. modernMerkCard.layer.borderColor = UIColor(red: 235/255, green: 240/255, blue: 248/255, alpha: 1.0).cgColor
  180. let merkInnerStack = UIStackView()
  181. merkInnerStack.translatesAutoresizingMaskIntoConstraints = false
  182. merkInnerStack.axis = .vertical
  183. merkInnerStack.spacing = 2
  184. modernMerkCard.addSubview(merkInnerStack)
  185. modernMerkTitle.font = UIFont.systemFont(ofSize: 9, weight: .bold)
  186. modernMerkTitle.textColor = UIColor(red: 140/255, green: 155/255, blue: 175/255, alpha: 1.0)
  187. modernMerkTitle.text = "MERK & MODEL"
  188. merkInnerStack.addArrangedSubview(modernMerkTitle)
  189. modernMerkVal.font = UIFont.systemFont(ofSize: 11, weight: .semibold)
  190. modernMerkVal.textColor = UIColor(red: 40/255, green: 50/255, blue: 65/255, alpha: 1.0)
  191. modernMerkVal.numberOfLines = 1
  192. merkInnerStack.addArrangedSubview(modernMerkVal)
  193. NSLayoutConstraint.activate([
  194. merkInnerStack.topAnchor.constraint(equalTo: modernMerkCard.topAnchor, constant: 6),
  195. merkInnerStack.bottomAnchor.constraint(equalTo: modernMerkCard.bottomAnchor, constant: -6),
  196. merkInnerStack.leadingAnchor.constraint(equalTo: modernMerkCard.leadingAnchor, constant: 8),
  197. merkInnerStack.trailingAnchor.constraint(equalTo: modernMerkCard.trailingAnchor, constant: -8)
  198. ])
  199. modernSpecStack.addArrangedSubview(modernMerkCard)
  200. // PLG Card
  201. modernPlgCard.backgroundColor = UIColor(red: 248/255, green: 250/255, blue: 253/255, alpha: 1.0)
  202. modernPlgCard.layer.cornerRadius = 8
  203. modernPlgCard.layer.borderWidth = 1
  204. modernPlgCard.layer.borderColor = UIColor(red: 235/255, green: 240/255, blue: 248/255, alpha: 1.0).cgColor
  205. let plgInnerStack = UIStackView()
  206. plgInnerStack.translatesAutoresizingMaskIntoConstraints = false
  207. plgInnerStack.axis = .vertical
  208. plgInnerStack.spacing = 2
  209. modernPlgCard.addSubview(plgInnerStack)
  210. modernPlgTitle.font = UIFont.systemFont(ofSize: 9, weight: .bold)
  211. modernPlgTitle.textColor = UIColor(red: 140/255, green: 155/255, blue: 175/255, alpha: 1.0)
  212. modernPlgTitle.text = "ID PELANGGAN"
  213. plgInnerStack.addArrangedSubview(modernPlgTitle)
  214. modernPlgVal.font = UIFont.systemFont(ofSize: 11, weight: .semibold)
  215. modernPlgVal.textColor = UIColor(red: 40/255, green: 50/255, blue: 65/255, alpha: 1.0)
  216. modernPlgVal.numberOfLines = 1
  217. plgInnerStack.addArrangedSubview(modernPlgVal)
  218. NSLayoutConstraint.activate([
  219. plgInnerStack.topAnchor.constraint(equalTo: modernPlgCard.topAnchor, constant: 6),
  220. plgInnerStack.bottomAnchor.constraint(equalTo: modernPlgCard.bottomAnchor, constant: -6),
  221. plgInnerStack.leadingAnchor.constraint(equalTo: modernPlgCard.leadingAnchor, constant: 8),
  222. plgInnerStack.trailingAnchor.constraint(equalTo: modernPlgCard.trailingAnchor, constant: -8)
  223. ])
  224. modernSpecStack.addArrangedSubview(modernPlgCard)
  225. // 6. Validity Bar
  226. modernValidityCard.translatesAutoresizingMaskIntoConstraints = false
  227. modernValidityCard.backgroundColor = UIColor(red: 244/255, green: 248/255, blue: 254/255, alpha: 1.0)
  228. modernValidityCard.layer.cornerRadius = 8
  229. modernContainer.addSubview(modernValidityCard)
  230. let validityStack = UIStackView()
  231. validityStack.translatesAutoresizingMaskIntoConstraints = false
  232. validityStack.axis = .horizontal
  233. validityStack.alignment = .center
  234. validityStack.spacing = 6
  235. modernValidityCard.addSubview(validityStack)
  236. if #available(iOS 13.0, *) {
  237. modernCalendarIcon.image = UIImage(systemName: "calendar")
  238. }
  239. modernCalendarIcon.tintColor = UIColor.siraniPrimaryBlue
  240. modernCalendarIcon.contentMode = .scaleAspectFit
  241. modernCalendarIcon.translatesAutoresizingMaskIntoConstraints = false
  242. NSLayoutConstraint.activate([
  243. modernCalendarIcon.widthAnchor.constraint(equalToConstant: 13),
  244. modernCalendarIcon.heightAnchor.constraint(equalToConstant: 13)
  245. ])
  246. validityStack.addArrangedSubview(modernCalendarIcon)
  247. modernValidityLabel.font = UIFont.systemFont(ofSize: 11, weight: .medium)
  248. modernValidityLabel.textColor = UIColor(red: 50/255, green: 70/255, blue: 95/255, alpha: 1.0)
  249. modernValidityLabel.numberOfLines = 1
  250. validityStack.addArrangedSubview(modernValidityLabel)
  251. let spacer = UIView()
  252. spacer.setContentHuggingPriority(.defaultLow, for: .horizontal)
  253. validityStack.addArrangedSubview(spacer)
  254. modernDetailLabel.font = UIFont.systemFont(ofSize: 11, weight: .bold)
  255. modernDetailLabel.textColor = UIColor.siraniPrimaryBlue
  256. modernDetailLabel.text = "Detail"
  257. validityStack.addArrangedSubview(modernDetailLabel)
  258. if #available(iOS 13.0, *) {
  259. modernChevronIcon.image = UIImage(systemName: "chevron.right")
  260. }
  261. modernChevronIcon.tintColor = UIColor.siraniPrimaryBlue
  262. modernChevronIcon.contentMode = .scaleAspectFit
  263. modernChevronIcon.translatesAutoresizingMaskIntoConstraints = false
  264. NSLayoutConstraint.activate([
  265. modernChevronIcon.widthAnchor.constraint(equalToConstant: 10),
  266. modernChevronIcon.heightAnchor.constraint(equalToConstant: 10)
  267. ])
  268. validityStack.addArrangedSubview(modernChevronIcon)
  269. NSLayoutConstraint.activate([
  270. validityStack.topAnchor.constraint(equalTo: modernValidityCard.topAnchor, constant: 6),
  271. validityStack.bottomAnchor.constraint(equalTo: modernValidityCard.bottomAnchor, constant: -6),
  272. validityStack.leadingAnchor.constraint(equalTo: modernValidityCard.leadingAnchor, constant: 10),
  273. validityStack.trailingAnchor.constraint(equalTo: modernValidityCard.trailingAnchor, constant: -10)
  274. ])
  275. NSLayoutConstraint.activate([
  276. headerStack.topAnchor.constraint(equalTo: modernContainer.topAnchor),
  277. headerStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  278. headerStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  279. divider.topAnchor.constraint(equalTo: headerStack.bottomAnchor, constant: 10),
  280. divider.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  281. divider.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  282. divider.heightAnchor.constraint(equalToConstant: 1),
  283. modernPerangkatLabel.topAnchor.constraint(equalTo: divider.bottomAnchor, constant: 10),
  284. modernPerangkatLabel.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  285. modernPerangkatLabel.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  286. companyStack.topAnchor.constraint(equalTo: modernPerangkatLabel.bottomAnchor, constant: 6),
  287. companyStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  288. companyStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  289. modernSpecStack.topAnchor.constraint(equalTo: companyStack.bottomAnchor, constant: 10),
  290. modernSpecStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  291. modernSpecStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  292. modernValidityCard.topAnchor.constraint(equalTo: modernSpecStack.bottomAnchor, constant: 10),
  293. modernValidityCard.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  294. modernValidityCard.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  295. modernValidityCard.bottomAnchor.constraint(equalTo: modernContainer.bottomAnchor)
  296. ])
  297. }
  298. func updateViews(certificateData: CertificateData) {
  299. setupCardVisuals()
  300. setupModernLayout()
  301. card.isInteractable = true
  302. let gesture = UITapGestureRecognizer(target: self, action: #selector(self.onItemTap))
  303. card.addGestureRecognizer(gesture)
  304. modernNomorLabel.text = certificateData.nomor.isEmpty ? "-" : certificateData.nomor
  305. let statusStr = certificateData.statusBerlaku.trimmingCharacters(in: .whitespacesAndNewlines)
  306. modernStatusLabel.text = statusStr.isEmpty ? "BERLAKU" : statusStr.uppercased()
  307. modernPerangkatLabel.text = certificateData.eqp_name.isEmpty ? "-" : certificateData.eqp_name
  308. modernPemohonLabel.text = certificateData.cust_name.isEmpty ? "-" : certificateData.cust_name
  309. modernMerkVal.text = certificateData.models.isEmpty ? "-" : certificateData.models
  310. modernPlgVal.text = certificateData.plg_id == 0 ? "-" : "\(certificateData.plg_id)"
  311. let expDate = CommonHelper.formatDate(from: certificateData.exp_date)
  312. modernValidityLabel.text = expDate == "-" ? "Masa Berlaku: -" : "Berakhir: \(expDate)"
  313. self.dataSertifikat = certificateData
  314. }
  315. @objc func onItemTap(sender: UITapGestureRecognizer) {
  316. cellDelegate?.openSertifikatDetail(data: dataSertifikat)
  317. }
  318. }