SertifikatBerlakuCell.swift 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. //
  2. // SertifikatBerlakuCell.swift
  3. // Sirani
  4. //
  5. // Created by Anhar Solehudin on 22/04/19.
  6. // Copyright © 2019 Anhar Solehudin. All rights reserved.
  7. //
  8. import UIKit
  9. import MaterialComponents.MaterialCards
  10. class SertifikatBerlakuCell: UITableViewCell {
  11. @IBOutlet weak var card: MDCCard!
  12. @IBOutlet weak var lblAplikasiId: UILabel!
  13. @IBOutlet weak var lblNo: UILabel!
  14. @IBOutlet weak var lblTgl: UILabel!
  15. @IBOutlet weak var lblCustName: UILabel!
  16. @IBOutlet weak var lblEqpName: UILabel!
  17. @IBOutlet weak var lblMerk: UILabel!
  18. @IBOutlet weak var lblModel: UILabel!
  19. @IBOutlet weak var lblNegara: UILabel!
  20. // Modern Programmatic UI Elements
  21. private let modernContainer = UIView()
  22. private let modernBadgeView = UIView()
  23. private let modernBadgeIcon = UIImageView()
  24. private let modernNomorLabel = UILabel()
  25. private let modernCategoryLabel = UILabel()
  26. private let modernStatusPill = UIView()
  27. private let modernStatusLabel = UILabel()
  28. private let modernPerangkatLabel = UILabel()
  29. private let modernCompanyIcon = UIImageView()
  30. private let modernPemohonLabel = UILabel()
  31. private let modernSpecStack = UIStackView()
  32. private let modernMerkCard = UIView()
  33. private let modernMerkTitle = UILabel()
  34. private let modernMerkVal = UILabel()
  35. private let modernNegaraCard = UIView()
  36. private let modernNegaraTitle = UILabel()
  37. private let modernNegaraVal = UILabel()
  38. private let modernValidityCard = UIView()
  39. private let modernCalendarIcon = UIImageView()
  40. private let modernValidityLabel = UILabel()
  41. private let modernAplIdLabel = UILabel()
  42. private var isModernLayoutBuilt = false
  43. override func awakeFromNib() {
  44. super.awakeFromNib()
  45. self.selectionStyle = .none
  46. self.backgroundColor = .clear
  47. setupCardVisuals()
  48. setupModernLayout()
  49. }
  50. private func setupCardVisuals() {
  51. guard let card = card else { return }
  52. card.cornerRadius = 16
  53. card.setShadowElevation(ShadowElevation(rawValue: 2), for: .normal)
  54. card.setShadowColor(UIColor.black.withAlphaComponent(0.06), for: .normal)
  55. card.layer.borderColor = UIColor(red: 228/255, green: 235/255, blue: 245/255, alpha: 1.0).cgColor
  56. card.layer.borderWidth = 1.0
  57. card.backgroundColor = .white
  58. }
  59. private func setupModernLayout() {
  60. guard let card = card, !isModernLayoutBuilt else { return }
  61. isModernLayoutBuilt = true
  62. for subview in card.subviews {
  63. subview.isHidden = true
  64. }
  65. modernContainer.translatesAutoresizingMaskIntoConstraints = false
  66. modernContainer.backgroundColor = .clear
  67. card.addSubview(modernContainer)
  68. NSLayoutConstraint.activate([
  69. modernContainer.topAnchor.constraint(equalTo: card.topAnchor, constant: 14),
  70. modernContainer.bottomAnchor.constraint(equalTo: card.bottomAnchor, constant: -14),
  71. modernContainer.leadingAnchor.constraint(equalTo: card.leadingAnchor, constant: 14),
  72. modernContainer.trailingAnchor.constraint(equalTo: card.trailingAnchor, constant: -14)
  73. ])
  74. // 1. Header Bar
  75. let headerStack = UIStackView()
  76. headerStack.translatesAutoresizingMaskIntoConstraints = false
  77. headerStack.axis = .horizontal
  78. headerStack.alignment = .center
  79. headerStack.spacing = 10
  80. modernContainer.addSubview(headerStack)
  81. modernBadgeView.translatesAutoresizingMaskIntoConstraints = false
  82. modernBadgeView.backgroundColor = UIColor(red: 235/255, green: 242/255, blue: 252/255, alpha: 1.0)
  83. modernBadgeView.layer.cornerRadius = 8
  84. modernBadgeView.layer.masksToBounds = true
  85. modernBadgeIcon.translatesAutoresizingMaskIntoConstraints = false
  86. if #available(iOS 13.0, *) {
  87. modernBadgeIcon.image = UIImage(systemName: "checkmark.seal.fill")
  88. }
  89. modernBadgeIcon.tintColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
  90. modernBadgeIcon.contentMode = .scaleAspectFit
  91. modernBadgeView.addSubview(modernBadgeIcon)
  92. let titleStack = UIStackView()
  93. titleStack.translatesAutoresizingMaskIntoConstraints = false
  94. titleStack.axis = .vertical
  95. titleStack.spacing = 2
  96. modernCategoryLabel.translatesAutoresizingMaskIntoConstraints = false
  97. modernCategoryLabel.font = UIFont.systemFont(ofSize: 10, weight: .bold)
  98. modernCategoryLabel.textColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
  99. modernCategoryLabel.text = "SERTIFIKAT BERLAKU"
  100. modernNomorLabel.translatesAutoresizingMaskIntoConstraints = false
  101. modernNomorLabel.font = UIFont.systemFont(ofSize: 14, weight: .bold)
  102. modernNomorLabel.textColor = UIColor(red: 26/255, green: 32/255, blue: 44/255, alpha: 1.0)
  103. modernNomorLabel.numberOfLines = 1
  104. titleStack.addArrangedSubview(modernCategoryLabel)
  105. titleStack.addArrangedSubview(modernNomorLabel)
  106. modernStatusPill.translatesAutoresizingMaskIntoConstraints = false
  107. modernStatusPill.layer.cornerRadius = 12
  108. modernStatusPill.layer.masksToBounds = true
  109. modernStatusPill.backgroundColor = UIColor(red: 232/255, green: 248/255, blue: 240/255, alpha: 1.0)
  110. let statusDot = UIView()
  111. statusDot.translatesAutoresizingMaskIntoConstraints = false
  112. statusDot.layer.cornerRadius = 3.5
  113. statusDot.backgroundColor = UIColor(red: 16/255, green: 124/255, blue: 65/255, alpha: 1.0)
  114. modernStatusLabel.translatesAutoresizingMaskIntoConstraints = false
  115. modernStatusLabel.font = UIFont.systemFont(ofSize: 11, weight: .bold)
  116. modernStatusLabel.textColor = UIColor(red: 16/255, green: 124/255, blue: 65/255, alpha: 1.0)
  117. modernStatusLabel.text = "BERLAKU"
  118. let pillStack = UIStackView(arrangedSubviews: [statusDot, modernStatusLabel])
  119. pillStack.translatesAutoresizingMaskIntoConstraints = false
  120. pillStack.axis = .horizontal
  121. pillStack.spacing = 5
  122. pillStack.alignment = .center
  123. modernStatusPill.addSubview(pillStack)
  124. headerStack.addArrangedSubview(modernBadgeView)
  125. headerStack.addArrangedSubview(titleStack)
  126. headerStack.addArrangedSubview(modernStatusPill)
  127. // 2. Equipment Name
  128. modernPerangkatLabel.translatesAutoresizingMaskIntoConstraints = false
  129. modernPerangkatLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold)
  130. modernPerangkatLabel.textColor = UIColor(red: 26/255, green: 32/255, blue: 44/255, alpha: 1.0)
  131. modernPerangkatLabel.numberOfLines = 2
  132. modernContainer.addSubview(modernPerangkatLabel)
  133. // 3. Company Row
  134. let companyStack = UIStackView()
  135. companyStack.translatesAutoresizingMaskIntoConstraints = false
  136. companyStack.axis = .horizontal
  137. companyStack.spacing = 6
  138. companyStack.alignment = .center
  139. modernContainer.addSubview(companyStack)
  140. modernCompanyIcon.translatesAutoresizingMaskIntoConstraints = false
  141. if #available(iOS 13.0, *) {
  142. modernCompanyIcon.image = UIImage(systemName: "building.2.fill")
  143. }
  144. modernCompanyIcon.tintColor = UIColor(red: 113/255, green: 128/255, blue: 150/255, alpha: 1.0)
  145. modernCompanyIcon.contentMode = .scaleAspectFit
  146. modernPemohonLabel.translatesAutoresizingMaskIntoConstraints = false
  147. modernPemohonLabel.font = UIFont.systemFont(ofSize: 13, weight: .medium)
  148. modernPemohonLabel.textColor = UIColor(red: 74/255, green: 85/255, blue: 104/255, alpha: 1.0)
  149. modernPemohonLabel.numberOfLines = 1
  150. companyStack.addArrangedSubview(modernCompanyIcon)
  151. companyStack.addArrangedSubview(modernPemohonLabel)
  152. // 4. Spec Stack (Merk & Model | Negara)
  153. modernSpecStack.translatesAutoresizingMaskIntoConstraints = false
  154. modernSpecStack.axis = .horizontal
  155. modernSpecStack.distribution = .fillEqually
  156. modernSpecStack.spacing = 8
  157. modernContainer.addSubview(modernSpecStack)
  158. func styleMiniCard(_ cardView: UIView, titleLabel: UILabel, valLabel: UILabel, title: String) {
  159. cardView.translatesAutoresizingMaskIntoConstraints = false
  160. cardView.backgroundColor = UIColor(red: 248/255, green: 250/255, blue: 253/255, alpha: 1.0)
  161. cardView.layer.cornerRadius = 8
  162. cardView.layer.borderColor = UIColor(red: 235/255, green: 240/255, blue: 248/255, alpha: 1.0).cgColor
  163. cardView.layer.borderWidth = 1
  164. titleLabel.translatesAutoresizingMaskIntoConstraints = false
  165. titleLabel.font = UIFont.systemFont(ofSize: 10, weight: .semibold)
  166. titleLabel.textColor = UIColor(red: 113/255, green: 128/255, blue: 150/255, alpha: 1.0)
  167. titleLabel.text = title
  168. valLabel.translatesAutoresizingMaskIntoConstraints = false
  169. valLabel.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
  170. valLabel.textColor = UIColor(red: 45/255, green: 55/255, blue: 72/255, alpha: 1.0)
  171. valLabel.numberOfLines = 1
  172. let stack = UIStackView(arrangedSubviews: [titleLabel, valLabel])
  173. stack.translatesAutoresizingMaskIntoConstraints = false
  174. stack.axis = .vertical
  175. stack.spacing = 2
  176. cardView.addSubview(stack)
  177. NSLayoutConstraint.activate([
  178. stack.topAnchor.constraint(equalTo: cardView.topAnchor, constant: 6),
  179. stack.bottomAnchor.constraint(equalTo: cardView.bottomAnchor, constant: -6),
  180. stack.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 8),
  181. stack.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -8)
  182. ])
  183. }
  184. styleMiniCard(modernMerkCard, titleLabel: modernMerkTitle, valLabel: modernMerkVal, title: "MERK & MODEL")
  185. styleMiniCard(modernNegaraCard, titleLabel: modernNegaraTitle, valLabel: modernNegaraVal, title: "NEGARA PEMBUAT")
  186. modernSpecStack.addArrangedSubview(modernMerkCard)
  187. modernSpecStack.addArrangedSubview(modernNegaraCard)
  188. // 5. Validity Footer Bar
  189. modernValidityCard.translatesAutoresizingMaskIntoConstraints = false
  190. modernValidityCard.backgroundColor = UIColor(red: 244/255, green: 248/255, blue: 254/255, alpha: 1.0)
  191. modernValidityCard.layer.cornerRadius = 10
  192. modernContainer.addSubview(modernValidityCard)
  193. modernCalendarIcon.translatesAutoresizingMaskIntoConstraints = false
  194. if #available(iOS 13.0, *) {
  195. modernCalendarIcon.image = UIImage(systemName: "calendar")
  196. }
  197. modernCalendarIcon.tintColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
  198. modernCalendarIcon.contentMode = .scaleAspectFit
  199. modernValidityLabel.translatesAutoresizingMaskIntoConstraints = false
  200. modernValidityLabel.font = UIFont.systemFont(ofSize: 11, weight: .medium)
  201. modernValidityLabel.textColor = UIColor(red: 74/255, green: 85/255, blue: 104/255, alpha: 1.0)
  202. modernAplIdLabel.translatesAutoresizingMaskIntoConstraints = false
  203. modernAplIdLabel.font = UIFont.systemFont(ofSize: 10, weight: .bold)
  204. modernAplIdLabel.textColor = UIColor(red: 0/255, green: 82/255, blue: 204/255, alpha: 1.0)
  205. let validityContentStack = UIStackView(arrangedSubviews: [modernCalendarIcon, modernValidityLabel])
  206. validityContentStack.translatesAutoresizingMaskIntoConstraints = false
  207. validityContentStack.axis = .horizontal
  208. validityContentStack.spacing = 6
  209. validityContentStack.alignment = .center
  210. let footerStack = UIStackView(arrangedSubviews: [validityContentStack, modernAplIdLabel])
  211. footerStack.translatesAutoresizingMaskIntoConstraints = false
  212. footerStack.axis = .horizontal
  213. footerStack.distribution = .equalSpacing
  214. footerStack.alignment = .center
  215. modernValidityCard.addSubview(footerStack)
  216. // Constraints
  217. NSLayoutConstraint.activate([
  218. headerStack.topAnchor.constraint(equalTo: modernContainer.topAnchor),
  219. headerStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  220. headerStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  221. modernBadgeView.widthAnchor.constraint(equalToConstant: 34),
  222. modernBadgeView.heightAnchor.constraint(equalToConstant: 34),
  223. modernBadgeIcon.centerXAnchor.constraint(equalTo: modernBadgeView.centerXAnchor),
  224. modernBadgeIcon.centerYAnchor.constraint(equalTo: modernBadgeView.centerYAnchor),
  225. modernBadgeIcon.widthAnchor.constraint(equalToConstant: 18),
  226. modernBadgeIcon.heightAnchor.constraint(equalToConstant: 18),
  227. statusDot.widthAnchor.constraint(equalToConstant: 7),
  228. statusDot.heightAnchor.constraint(equalToConstant: 7),
  229. pillStack.topAnchor.constraint(equalTo: modernStatusPill.topAnchor, constant: 5),
  230. pillStack.bottomAnchor.constraint(equalTo: modernStatusPill.bottomAnchor, constant: -5),
  231. pillStack.leadingAnchor.constraint(equalTo: modernStatusPill.leadingAnchor, constant: 10),
  232. pillStack.trailingAnchor.constraint(equalTo: modernStatusPill.trailingAnchor, constant: -10),
  233. modernPerangkatLabel.topAnchor.constraint(equalTo: headerStack.bottomAnchor, constant: 10),
  234. modernPerangkatLabel.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  235. modernPerangkatLabel.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  236. companyStack.topAnchor.constraint(equalTo: modernPerangkatLabel.bottomAnchor, constant: 6),
  237. companyStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  238. companyStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  239. modernCompanyIcon.widthAnchor.constraint(equalToConstant: 14),
  240. modernCompanyIcon.heightAnchor.constraint(equalToConstant: 14),
  241. modernSpecStack.topAnchor.constraint(equalTo: companyStack.bottomAnchor, constant: 10),
  242. modernSpecStack.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  243. modernSpecStack.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  244. modernValidityCard.topAnchor.constraint(equalTo: modernSpecStack.bottomAnchor, constant: 10),
  245. modernValidityCard.leadingAnchor.constraint(equalTo: modernContainer.leadingAnchor),
  246. modernValidityCard.trailingAnchor.constraint(equalTo: modernContainer.trailingAnchor),
  247. modernValidityCard.bottomAnchor.constraint(equalTo: modernContainer.bottomAnchor),
  248. modernCalendarIcon.widthAnchor.constraint(equalToConstant: 13),
  249. modernCalendarIcon.heightAnchor.constraint(equalToConstant: 13),
  250. footerStack.topAnchor.constraint(equalTo: modernValidityCard.topAnchor, constant: 8),
  251. footerStack.bottomAnchor.constraint(equalTo: modernValidityCard.bottomAnchor, constant: -8),
  252. footerStack.leadingAnchor.constraint(equalTo: modernValidityCard.leadingAnchor, constant: 10),
  253. footerStack.trailingAnchor.constraint(equalTo: modernValidityCard.trailingAnchor, constant: -10)
  254. ])
  255. }
  256. func updateViews(sertifikatBerlaku: SertifikatBerlaku) {
  257. card?.isInteractable = false
  258. setupModernLayout()
  259. let nomor = sertifikatBerlaku.nomor.isEmpty ? "-" : sertifikatBerlaku.nomor
  260. modernNomorLabel.text = nomor
  261. lblNo?.text = nomor
  262. let tglFormatted = CommonHelper.formatDate(from: sertifikatBerlaku.tgl)
  263. let expFormatted = CommonHelper.formatDate(from: sertifikatBerlaku.exp)
  264. modernValidityLabel.text = "\(tglFormatted) s/d \(expFormatted)"
  265. lblTgl?.text = "\(tglFormatted) s/d \(expFormatted)"
  266. let cust = sertifikatBerlaku.cust_name.isEmpty ? "-" : sertifikatBerlaku.cust_name
  267. modernPemohonLabel.text = cust
  268. lblCustName?.text = cust
  269. let eqp = sertifikatBerlaku.eqp_name.isEmpty ? "-" : sertifikatBerlaku.eqp_name
  270. modernPerangkatLabel.text = eqp
  271. lblEqpName?.text = eqp
  272. var merk = "-"
  273. var model = "-"
  274. let models = sertifikatBerlaku.models
  275. let values = models.split(separator: "&")
  276. if values.count > 0 {
  277. let m = String(values[0]).trimmingCharacters(in: .whitespacesAndNewlines)
  278. if !m.isEmpty { merk = m }
  279. }
  280. if values.count > 1 {
  281. let mod = String(values[1]).trimmingCharacters(in: .whitespacesAndNewlines)
  282. if !mod.isEmpty { model = mod }
  283. }
  284. modernMerkVal.text = "\(merk) / \(model)"
  285. lblMerk?.text = "Merk: \(merk)"
  286. lblModel?.text = "Model: \(model)"
  287. let negara = sertifikatBerlaku.negara.isEmpty ? "-" : sertifikatBerlaku.negara
  288. modernNegaraVal.text = negara
  289. lblNegara?.text = negara
  290. modernAplIdLabel.text = "ID: \(sertifikatBerlaku.apl_id)"
  291. lblAplikasiId?.text = "\(sertifikatBerlaku.apl_id)"
  292. }
  293. }