AplikasiDitolakCell.swift 20 KB

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