Parcourir la source

sertifikat public and add label negara

Hendi il y a 3 ans
Parent
commit
b20663a633

+ 12 - 0
Sirani.xcodeproj/project.pbxproj

@@ -19,6 +19,7 @@
 		048A265B2A42E621008CDB82 /* AplikasiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 048A265A2A42E621008CDB82 /* AplikasiCell.swift */; };
 		048A265D2A42E636008CDB82 /* SearchAplikasiVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 048A265C2A42E636008CDB82 /* SearchAplikasiVC.swift */; };
 		048A265F2A42F48F008CDB82 /* Aplikasi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 048A265E2A42F48F008CDB82 /* Aplikasi.swift */; };
+		048A26622A443550008CDB82 /* SertifikatPublicVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 048A26612A443550008CDB82 /* SertifikatPublicVC.swift */; };
 		04CAAAD12A4007B9005DBD04 /* SertifikatNewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04CAAAD02A4007B9005DBD04 /* SertifikatNewCell.swift */; };
 		04CAAAD42A4042C4005DBD04 /* SearchSertifikatNewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04CAAAD32A4042C4005DBD04 /* SearchSertifikatNewVC.swift */; };
 		04D0FD7E2A31B3EF00DC89D1 /* SertifikatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D0FD7D2A31B3EF00DC89D1 /* SertifikatViewController.swift */; };
@@ -246,6 +247,7 @@
 		048A265A2A42E621008CDB82 /* AplikasiCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AplikasiCell.swift; sourceTree = "<group>"; };
 		048A265C2A42E636008CDB82 /* SearchAplikasiVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchAplikasiVC.swift; sourceTree = "<group>"; };
 		048A265E2A42F48F008CDB82 /* Aplikasi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Aplikasi.swift; sourceTree = "<group>"; };
+		048A26612A443550008CDB82 /* SertifikatPublicVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SertifikatPublicVC.swift; sourceTree = "<group>"; };
 		04CAAAD02A4007B9005DBD04 /* SertifikatNewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SertifikatNewCell.swift; sourceTree = "<group>"; };
 		04CAAAD32A4042C4005DBD04 /* SearchSertifikatNewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSertifikatNewVC.swift; sourceTree = "<group>"; };
 		04D0FD7D2A31B3EF00DC89D1 /* SertifikatViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SertifikatViewController.swift; sourceTree = "<group>"; };
@@ -493,6 +495,14 @@
 			path = Label;
 			sourceTree = "<group>";
 		};
+		048A26602A4434FE008CDB82 /* SertifikatPublic */ = {
+			isa = PBXGroup;
+			children = (
+				048A26612A443550008CDB82 /* SertifikatPublicVC.swift */,
+			);
+			path = SertifikatPublic;
+			sourceTree = "<group>";
+		};
 		04CAAAD22A404294005DBD04 /* Search */ = {
 			isa = PBXGroup;
 			children = (
@@ -533,6 +543,7 @@
 		FC06F76A226E0C2E00B574E4 /* Sertifikat */ = {
 			isa = PBXGroup;
 			children = (
+				048A26602A4434FE008CDB82 /* SertifikatPublic */,
 				04CAAAD22A404294005DBD04 /* Search */,
 				04D0FD822A32E42D00DC89D1 /* SertifikatPresenter.swift */,
 				04D0FD842A33027E00DC89D1 /* SertifikatViewDelegate.swift */,
@@ -1534,6 +1545,7 @@
 				FC6B67992268974F0042656E /* OdsSp2BaruCell.swift in Sources */,
 				FCEE51F4225FF668000AE43B /* HasilSurveyViewDelegate.swift in Sources */,
 				FC6A5D88227299730096664E /* SertifikatTidakBerlakuPresenter.swift in Sources */,
+				048A26622A443550008CDB82 /* SertifikatPublicVC.swift in Sources */,
 				048A26592A42E612008CDB82 /* AplikasiPresenter.swift in Sources */,
 				FCF7BAF32263143200532DC2 /* OdsSp2PrintCell.swift in Sources */,
 				FC8568F2225116100012F927 /* InformasiSertifikasiVC.swift in Sources */,

BIN
Sirani.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate


+ 2 - 3
Sirani/ApiServices/SiraniApiServices.swift

@@ -667,14 +667,13 @@ class SiraniApiServices {
     
 //    ------------------------------------------- NEW FUNCTION -------------------------------------------
     
-    func postToGetSertifikatPublic(user_id: Int, cust_id: Int, role_id: String, jenis: String, columns: String, limit: Int, page: Int, search: String) -> DataRequest {
+    func postToGetSertifikatPublic(user_id: Int, cust_id: Int, role_id: String, status: String, limit: Int, page: Int, search: String) -> DataRequest {
         let headers: HTTPHeaders = ["Accept" : "Application/json; charset=utf-8"]
         let body: Parameters = [
             "user_id" : String(user_id),
             "cust_id" : String(cust_id),
             "role_id" : role_id,
-            "jenis" : jenis,
-            "columns" : columns,
+            "status" : status,
             "limit" : String(limit),
             "page" : String(page),
             "search" : search

Fichier diff supprimé car celui-ci est trop grand
+ 750 - 160
Sirani/Base.lproj/Main.storyboard


+ 2 - 1
Sirani/Utils/MenuListData.swift

@@ -34,7 +34,8 @@ class MenuListData {
     let menuUtamaCellId = "menuUtamaCellId"
     let moreMenuUtamaCellId = "moreMenuUtamaCellId"
     private let menuUtamaItems = [
-        MenuItem(segueId: "DaftarSertifikatSegueId", icon: "menu-utama-daftar-sertifikat.png", name: "Daftar Sertifikat", totalNotif: 0),
+//        MenuItem(segueId: "DaftarSertifikatSegueId", icon: "menu-utama-daftar-sertifikat.png", name: "Daftar Sertifikat", totalNotif: 0),
+        MenuItem(segueId: "SertifikatPublicSegueId", icon: "menu-utama-daftar-sertifikat.png", name: "Sertifikat", totalNotif: 0),
         MenuItem(segueId: "TarifSertifikatSegueId", icon: "menu-utama-tarif-sertifikat.png", name: "Tarif Sertifikat", totalNotif: 0),
         MenuItem(segueId: "InformasiSertifikasiSegueId", icon: "menu-utama-informasi-sertifikat.png", name: "Informasi Sertifikasi", totalNotif: 0),
         MenuItem(segueId: "BalaiUjiSegueId", icon: "menu-utama-balai-uji.png", name: "Balai Uji", totalNotif: 0)

+ 29 - 21
Sirani/View/Home/HomeVC.swift

@@ -132,6 +132,8 @@ class HomeVC: UIViewController {
     override func viewWillAppear(_ animated: Bool) {
         AppUtility.lockOrientation(.portrait)
         
+        checkUserState()
+        
         btnMoreMenu.layer.cornerRadius = 5
         btnMoreNews.layer.cornerRadius = 5
         
@@ -149,10 +151,7 @@ class HomeVC: UIViewController {
         userRoleId = UserState.instance.getRoleId()
         let userId = UserState.instance.getUserId()
         let custId = UserState.instance.getCustId()
-        print("userRoleId")
-        print(userRoleId)
-        print(userId)
-        print(custId)
+
         if !userRoleId.isEmpty {
             showNotif()
         } else {
@@ -172,19 +171,19 @@ class HomeVC: UIViewController {
         
         setMainMenu()
         setNewsView()
-        setMoreMainMenu()
+//        setMoreMainMenu()
         
         userRoleId = UserState.instance.getRoleId()
         if !userRoleId.isEmpty {
             setMoreMenuUtamaNew(userRoleId: userRoleId)
-            setMoreMenuAplikasiODS(userRoleId: userRoleId)
-            setMoreMenuFotoLabel(userRoleId: userRoleId)
-            setMoreMenuAplikasi(userRoleId: userRoleId)
-            setMoreMenuSP2Sertifikat(userRoleId: userRoleId)
-            setMoreMenuSP2Tambahan(userRoleId: userRoleId)
-            setMoreMenuDaftarRHU(userRoleId: userRoleId)
-            setMoreMenuSertifikat(userRoleId: userRoleId)
-            setMoreMenuSurvey(userRoleId: userRoleId)
+//            setMoreMenuAplikasiODS(userRoleId: userRoleId)
+//            setMoreMenuFotoLabel(userRoleId: userRoleId)
+//            setMoreMenuAplikasi(userRoleId: userRoleId)
+//            setMoreMenuSP2Sertifikat(userRoleId: userRoleId)
+//            setMoreMenuSP2Tambahan(userRoleId: userRoleId)
+//            setMoreMenuDaftarRHU(userRoleId: userRoleId)
+//            setMoreMenuSertifikat(userRoleId: userRoleId)
+//            setMoreMenuSurvey(userRoleId: userRoleId)
             showNotif()
         } else {
             hideNotif()
@@ -210,14 +209,14 @@ class HomeVC: UIViewController {
             if !userRoleId.isEmpty {
                 clearMoreMenu()
                 setMoreMenuUtamaNew(userRoleId: userRoleId)
-                setMoreMenuAplikasiODS(userRoleId: userRoleId)
-                setMoreMenuFotoLabel(userRoleId: userRoleId)
-                setMoreMenuAplikasi(userRoleId: userRoleId)
-                setMoreMenuSP2Sertifikat(userRoleId: userRoleId)
-                setMoreMenuSP2Tambahan(userRoleId: userRoleId)
-                setMoreMenuDaftarRHU(userRoleId: userRoleId)
-                setMoreMenuSertifikat(userRoleId: userRoleId)
-                setMoreMenuSurvey(userRoleId: userRoleId)
+//                setMoreMenuAplikasiODS(userRoleId: userRoleId)
+//                setMoreMenuFotoLabel(userRoleId: userRoleId)
+//                setMoreMenuAplikasi(userRoleId: userRoleId)
+//                setMoreMenuSP2Sertifikat(userRoleId: userRoleId)
+//                setMoreMenuSP2Tambahan(userRoleId: userRoleId)
+//                setMoreMenuDaftarRHU(userRoleId: userRoleId)
+//                setMoreMenuSertifikat(userRoleId: userRoleId)
+//                setMoreMenuSurvey(userRoleId: userRoleId)
                 clearMoreMenuNotifData()
                 presenter.loadMenuNotifications()
                 showNotif()
@@ -248,6 +247,15 @@ class HomeVC: UIViewController {
     }
     
     // private functions
+    private func checkUserState() {
+        let isLoggedIn = UserState.instance.isLoggedIn()
+        if isLoggedIn {
+            btnMoreMenu.show()
+        } else {
+            btnMoreMenu.hide()
+        }
+    }
+    
     private func showNotif() {
         notifContainer.show()
         presenter.loadTotalUnreadNotif()

+ 2 - 0
Sirani/View/Label/LabelCell.swift

@@ -25,6 +25,7 @@ class LabelCell: UITableViewCell {
     @IBOutlet weak var lblBerlakuDate: UILabel!
     @IBOutlet weak var lblBerakhirDate: UILabel!
     @IBOutlet weak var lblStatus: UILabel!
+    @IBOutlet weak var lblNegara: UILabel!
 
     var cellDelegate: LabelCellDelegate?
     var dataLabel: Label?
@@ -40,6 +41,7 @@ class LabelCell: UITableViewCell {
         lblPerangkat.text = labelData.eqp_name
         lblMerk.text = labelData.merk
         lblModel.text = labelData.model
+        lblNegara.text = labelData.negara
         
         var brand = ""
         if labelData.brand != "null" {

+ 6 - 0
Sirani/View/ScanQR/Scanner/QRScannerVC.swift

@@ -69,6 +69,7 @@ class QRScannerVC: UIViewController {
     private var loading = false
     var kode : Int?
     var isSertifikatNew = false
+    var isSertifikatPublic = false
     
     // View Lifecycles
     override var preferredStatusBarStyle: UIStatusBarStyle {
@@ -194,8 +195,11 @@ class QRScannerVC: UIViewController {
     @IBAction func onBtnBackTap(_ sender: Any) {
         if(kode != nil)
         {
+            print("AJ \(isSertifikatPublic)")
             if(isSertifikatNew){
                 performSegue(withIdentifier: "unwindToSertifikatSegueId", sender: self)
+            }else if(isSertifikatPublic){
+                performSegue(withIdentifier: "unwindToSertifikatPublicSegueId", sender: self)
             }else{
                 performSegue(withIdentifier: "unwindToDaftarSertifikatSegueId", sender: self)
             }
@@ -211,6 +215,8 @@ class QRScannerVC: UIViewController {
         {
             if(isSertifikatNew){
                 performSegue(withIdentifier: "unwindToSertifikatSegueId", sender: self)
+            }else if(isSertifikatPublic){
+                performSegue(withIdentifier: "unwindToSertifikatPublicSegueId", sender: self)
             }else{
                 performSegue(withIdentifier: "unwindToDaftarSertifikatSegueId", sender: self)
             }

+ 39 - 10
Sirani/View/Sertifikat/Search/SearchSertifikatNewVC.swift

@@ -24,12 +24,21 @@ class SearchSertifikatNewVC: UIViewController {
     // Initialize
     var delegate: SearchSertifikatNewDelegate?
     
+    var backtoSertifikatPrivate = "unwindSearchToSertifikatSegueId"
+    var backtoSertifikatPublic = "unwindSearchToSertifikatPublicSegueId"
+    
+    var isSertifikat = 1
+    
     // constants vallue data
-    private let jenisSertifikatOptionItems = [
-        OptionItem(label: "Semua", value: ""),
-        OptionItem(label: "Berlaku", value: "sertifkat_berlaku"),
-        OptionItem(label: "Tidak Berlaku", value: "sertifikat_tidak_berlaku"),
-        OptionItem(label: "Revisi", value: "sertifikat_revisi")
+    private let statusSertifikatPrivateOptionItems = [
+        OptionItem(label: "Semua Sertifikat", value: ""),
+        OptionItem(label: "Sertifikat Berlaku", value: "sertifkat_berlaku"),
+        OptionItem(label: "Sertifikat Tidak Berlaku", value: "sertifikat_tidak_berlaku"),
+        OptionItem(label: "Sertifikat Revisi", value: "sertifikat_revisi")
+    ]
+    private let statusSertifikatPublicOptionItems = [
+        OptionItem(label: "Sertifikat Terbit", value: "sertifikat_terbit"),
+        OptionItem(label: "Sertifikat Dicabut", value: "sertifikat_dicabut")
     ]
     private let OPTION_JENIS_SERTIFIKAT_ID = 1
     
@@ -54,8 +63,14 @@ class SearchSertifikatNewVC: UIViewController {
         btnStatusOptions.layer.shadowOpacity = 0.5
         btnStatusOptions.layer.shadowOffset = CGSize(width: 1, height: 1)
         btnStatusOptions.layer.shadowRadius = 1
-        status = jenisSertifikatOptionItems[0].value as! String
-        jenisLabel = jenisSertifikatOptionItems[0].label
+        
+        if isSertifikat == 2 {
+            status = statusSertifikatPublicOptionItems[0].value as! String
+            jenisLabel = statusSertifikatPublicOptionItems[0].label
+        }else{
+            status = statusSertifikatPrivateOptionItems[0].value as! String
+            jenisLabel = statusSertifikatPrivateOptionItems[0].label
+        }
         btnStatusOptions.setTitle(jenisLabel, for: .normal)
         
         hideOptions()
@@ -80,14 +95,23 @@ class SearchSertifikatNewVC: UIViewController {
         if optionsShown {
             hideOptions()
         } else {
-            performSegue(withIdentifier: "unwindSearchToSertifikatSegueId", sender: self)
+            if isSertifikat == 2 {
+                performSegue(withIdentifier: backtoSertifikatPublic, sender: self)
+            }else {
+                performSegue(withIdentifier: backtoSertifikatPrivate, sender: self)
+            }
         }
     }
         
     @IBAction func onJenisSertifikatOptionsTapped(_ sender: Any) {
         selectedOptions = OPTION_JENIS_SERTIFIKAT_ID
         selectedOptionItems.removeAll()
-        selectedOptionItems += jenisSertifikatOptionItems
+        if isSertifikat == 2 {
+            selectedOptionItems += statusSertifikatPublicOptionItems
+        }else{
+            selectedOptionItems += statusSertifikatPrivateOptionItems
+        }
+        
         optionsLayoutTV.reloadData()
         showOptions()
     }
@@ -107,7 +131,12 @@ class SearchSertifikatNewVC: UIViewController {
         }
         
         self.delegate?.onSearch(search: search, status: status, jenisLabel: jenisLabel)
-        performSegue(withIdentifier: "unwindSearchToSertifikatSegueId", sender: self)
+        if isSertifikat == 2 {
+            performSegue(withIdentifier: backtoSertifikatPublic, sender: self)
+        }else {
+            performSegue(withIdentifier: backtoSertifikatPrivate, sender: self)
+        }
+
     }
     
     private func showOptions() {

+ 3 - 1
Sirani/View/Sertifikat/SertifikatNewCell.swift

@@ -25,6 +25,7 @@ class SertifikatNewCell: UITableViewCell {
     @IBOutlet weak var lblBerlakuDate: UILabel!
     @IBOutlet weak var lblBerakhirDate: UILabel!
     @IBOutlet weak var lblStatus: UILabel!
+    @IBOutlet weak var lblNegara: UILabel!
 
     var cellDelegate: SertifikatNewCellDelegate?
     var dataSertifikat: CertificateData?
@@ -40,7 +41,8 @@ class SertifikatNewCell: UITableViewCell {
         lblPerangkat.text = certificateData.eqp_name
         lblMerk.text = certificateData.merk
         lblModel.text = certificateData.model
-        
+        lblNegara.text = certificateData.negara
+
         var brand = ""
         if certificateData.brand != "null" {
             brand = certificateData.brand

+ 52 - 0
Sirani/View/Sertifikat/SertifikatPresenter.swift

@@ -77,6 +77,58 @@ class SertifikatPresenter {
         }
     }
     
+    func loadPublicCertificatesData(status: String, limit: Int, page: Int, search: String) {
+        self.view?.hideNoDataLayout()
+        self.view?.showLoading()
+        
+        var certificates = [CertificateData]()
+        siraniApiServices.postToGetSertifikatPublic(user_id: UserState.instance.getUserId(), cust_id: UserState.instance.getCustId(), role_id: UserState.instance.getRoleId(), status: status, limit: limit, page: page, search: search).responseJSON { response in
+            if response.error == nil {
+                guard let data = response.data else { return }
+                if let json = try? JSON(data: data) {
+                    if let data = json["data"].array {
+                        if data.count > 0 {
+                            for item in data {
+                                let certificateData = CertificateData(
+                                    nomor: item["nomor"].stringValue,
+                                    cust_name: item["cust_name"].stringValue,
+                                    eqp_name: item["eqp_name"].stringValue,
+                                    lic_id: item["lic_id"].intValue,
+                                    brand: item["brand"].stringValue,
+                                    lic_date: item["lic_date"].stringValue,
+                                    lic_no: item["lic_no"].stringValue,
+                                    exp_date: item["exp_date"].stringValue,
+                                    models: item["models"].stringValue,
+                                    plg_id: item["plg_id"].intValue,
+                                    apl_id: item["apl_id"].intValue,
+                                    negara: item["negara"].stringValue,
+                                    model: item["model"].stringValue,
+                                    merk: item["merk"].stringValue,
+                                    berlaku: item["berlaku"].stringValue
+                                )
+                                certificates.append(certificateData)
+                            }
+                            
+                            self.setCertificates(certificates: certificates)
+                        } else {
+                            if page > 1 {
+                                self.setCertificates(certificates: certificates)
+                            } else {
+                                self.showNoData()
+                            }
+                        }
+                    } else {
+                        self.showNoData()
+                    }
+                } else {
+                    self.showNoData()
+                }
+            } else {
+                self.showNoData()
+            }
+        }
+    }
+    
     // other functions
     private func setCertificates(certificates: [CertificateData]) {
         self.view?.setCertificates(certificates: certificates)

+ 229 - 0
Sirani/View/Sertifikat/SertifikatPublic/SertifikatPublicVC.swift

@@ -0,0 +1,229 @@
+//
+//  SertifikatPublicVC.swift
+//  Sirani
+//
+//  Created by Hendi on 22/06/23.
+//  Copyright © 2023 PT. Mitra Sinerji Teknoindo. All rights reserved.
+//
+
+import UIKit
+
+class SertifikatPublicVC: 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 sertifikatPublicCellId = "SertifikatPublicCell"
+    
+    // Segue Id
+    private let sertifikatPublicSearchSegueId = "searchSertifikatPublicSegueId"
+    private let unwindToHomeSegueId = "unwindSertifikatPublicToHomeSegueId"
+
+    // 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_terbit"
+    private var search: String = ""
+    
+    // Others
+    private var loading = false
+    private var lastDataLoadedEmpty = false
+    private var loadMore = false
+    private var kode: Int?
+    private var isSertifikatPublic: Bool = true
+    
+    // View Lifecycles
+    override var preferredStatusBarStyle: UIStatusBarStyle {
+        return .lightContent
+    }
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        certificatesTV.delegate = self
+        certificatesTV.dataSource = self
+        
+        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() {
+                presenter.loadPublicCertificatesData(status: status, limit: limit, page: page, search: search)
+            } else {
+                showNoConnection()
+            }
+        }
+    }
+    
+    // MARK: - Private Function
+    // Actions
+    @IBAction func onBtnBackTap(_ sender: Any) {
+        performSegue(withIdentifier: unwindToHomeSegueId, sender: self)
+    }
+    
+    @IBAction func onBtnSearchTap(_ sender: Any) {
+        performSegue(withIdentifier: sertifikatPublicSearchSegueId, sender: self)
+    }
+    
+    @IBAction func unwindToSertifikatPublic(segue: UIStoryboardSegue) {}
+
+}
+
+// View Delegate Protocols
+extension SertifikatPublicVC: 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 SertifikatPublicVC: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate, SertifikatNewCellDelegate {
+
+    func openSertifikatDetail(data: CertificateData?) {
+        self.kode = data?.apl_id
+        performSegue(withIdentifier: "sertifikatPublicDetailSegueId", 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: sertifikatPublicCellId, 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 SertifikatPublicVC: 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 == sertifikatPublicSearchSegueId {
+            let destinationVC: SearchSertifikatNewVC = segue.destination as! SearchSertifikatNewVC
+            destinationVC.delegate = self
+            destinationVC.isSertifikat = 2
+        }
+
+        if let detailSertifikatVC = segue.destination as? QRScannerVC {
+            detailSertifikatVC.kode = kode
+            detailSertifikatVC.isSertifikatPublic = isSertifikatPublic
+        }
+    }
+
+}