// // SertifikatViewController.swift // Sirani // // Created by Hendi on 08/06/23. // Copyright © 2026 PT. Mitra Sinerji Teknoindo. All rights reserved. // import UIKit class SertifikatViewController: UIViewController { // Outlets & Views @IBOutlet weak var certificatesTV: UITableView! @IBOutlet weak var progressLoading: UIView! @IBOutlet weak var layoutNoData: UIView! @IBOutlet weak var labelSubtitle: UILabel! // View Id private let sertifikatPrivateCellId = "SertifikatPrivateCell" // Segue Id private let sertifikatNewSearchSegueId = "searchSertifikatNewSegueId" private let searchSegueId = "searchSertifikatNewSegueId" // Initialize private var presenter: SertifikatPresenter! private var certificates: [CertificateData] = [CertificateData]() // Request Params private var limit: Int = 5 private var page: Int = 1 private var status: String = "sertifikat_all" private var search: String = "" // Others private var loading = false private var lastDataLoadedEmpty = false private var loadMore = false private var kode: Int? private var isSertifikatNew: Bool = true // View Lifecycles override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } override func viewDidLoad() { super.viewDidLoad() certificatesTV.delegate = self certificatesTV.dataSource = self certificatesTV.rowHeight = UITableView.automaticDimension certificatesTV.estimatedRowHeight = 220 presenter = SertifikatPresenter(siraniApiServices: SiraniApiServices()) presenter.attachView(view: self) loadCertificateData() } override func viewWillAppear(_ animated: Bool) { presenter.attachView(view: self) } override func viewDidDisappear(_ animated: Bool) { presenter.detachView() } // private functions private func loadCertificateData() { if !loading && !lastDataLoadedEmpty { if ConnectionHelper.isConnectedToNetwork() { self.presenter.loadPrivateCertificatesData(status: self.status, limit: self.limit, page: self.page, search: self.search) } else { showNoConnection() } } } // MARK: - Private Function // Actions @IBAction func onBtnSearchTap(_ sender: Any) { performSegue(withIdentifier: searchSegueId, sender: self) } @IBAction func unwindToSertifikat(segue: UIStoryboardSegue) {} } // View Delegate Protocols extension SertifikatViewController: SertifikatViewDelegate { func showNoConnection() { let alertNoConnection = UIAlertController( title: Constants.instance.ALERT_NO_CONNECTION_TITLE, message: Constants.instance.ALERT_NO_CONNECTION_MSG, preferredStyle: .alert ) alertNoConnection.addAction( UIAlertAction(title: Constants.instance.ALERT_NO_CONNECTION_YESS, style: .default, handler: nil) ) self.present(alertNoConnection, animated: true, completion: nil) } func showLoading() { loading = true progressLoading.show() } func hideLoading() { loading = false progressLoading.hide() } func showNoDataLayout() { if page == 1 { layoutNoData.show() } } func hideNoDataLayout() { layoutNoData.hide() } func setCertificates(certificates: [CertificateData]) { if page == 1 { layoutNoData.hide() } if certificates.count > 0 { for certificate in certificates { self.certificates.append(certificate) certificatesTV.beginUpdates() certificatesTV.insertRows( at: [IndexPath(row: self.certificates.count-1, section: 0)], with: .none ) certificatesTV.endUpdates() } page += 1 loadMore = true } else { lastDataLoadedEmpty = true loadMore = false } } } // UITableController Protocols extension SertifikatViewController: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate, SertifikatNewCellDelegate { func openSertifikatDetail(data: CertificateData?) { self.kode = data?.lic_id performSegue(withIdentifier: "sertifikatNewDetailSegueId", sender: self) } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return certificates.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if tableView == certificatesTV { if let cell = tableView.dequeueReusableCell(withIdentifier: sertifikatPrivateCellId, for: indexPath) as? SertifikatNewCell { cell.cellDelegate = self cell.card.tag = indexPath.row let certificate = certificates[indexPath.row] cell.updateViews(certificateData: certificate) return cell } else { return SertifikatNewCell() } } else { return SertifikatNewCell() } } func scrollViewDidScroll(_ scrollView: UIScrollView) { let threshold = -5 let contentOffset = scrollView.contentOffset.y let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height; if loadMore && !loading && (Int(maximumOffset - contentOffset) <= threshold) { loadCertificateData() } } } // SearchSertifikatNewModal Delegate Protocols extension SertifikatViewController: SearchSertifikatNewDelegate { func onSearch(search: String, status: String, jenisLabel: String) { presenter.attachView(view: self) loadMore = false loading = false lastDataLoadedEmpty = false self.limit = 5 self.page = 1 self.search = search self.status = status certificates.removeAll() certificatesTV.reloadData() labelSubtitle.text = jenisLabel loadCertificateData() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == sertifikatNewSearchSegueId { let destinationVC: SearchSertifikatNewVC = segue.destination as! SearchSertifikatNewVC destinationVC.delegate = self destinationVC.isSertifikat = 1 destinationVC.currentSearch = self.search destinationVC.currentStatus = self.status } if let detailSertifikatVC = segue.destination as? QRScannerVC { detailSertifikatVC.kode = kode detailSertifikatVC.isSertifikatNew = isSertifikatNew } } }