alqindiirsyam 2 anni fa
parent
commit
a03da2c052

+ 24 - 2
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -21,6 +21,12 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
     var switchSaveToGallery = UISwitch()
     var switchAutoDownload = UISwitch()
     
+    let separatorLogout = UIView()
+    let separatorNotifPersonal = UIView()
+    let separatorAutoDownload = UIView()
+    let separatorVersion = UIView()
+    let separatorLogin = UIView()
+    
     @IBOutlet weak var tableView: UITableView!
     @IBOutlet weak var backgroundImage: UIImageView!
     
@@ -31,7 +37,7 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
         
         tableView.delegate = self
         tableView.dataSource = self
-        tableView.layoutMargins = .init(top: 0, left: 5, bottom: 0, right: 5)
+        tableView.layoutMargins = .init(top: 0, left: 0, bottom: 0, right: 0)
 //        tableView.separatorColor = .gray
         tableView.separatorStyle = .none
         
@@ -321,6 +327,12 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
     
     public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
+        let isChangeProfile = Utils.getSetProfile()
+        if !isChangeProfile {
+            separatorLogout.removeFromSuperview()
+        } else {
+            separatorLogin.removeFromSuperview()
+        }
         cell.accessoryType = .none
         cell.indentationLevel = 0
         var content = cell.defaultContentConfiguration()
@@ -336,7 +348,6 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
             content.imageProperties.maximumSize = CGSize(width: 24, height: 24)
             content.text = menu.title
             cell.accessoryView = nil
-            cell.separatorInset = UIEdgeInsets(top: .greatestFiniteMagnitude, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
             switch menu.title {
             case "Personal Information".localized():
                 cell.accessoryType = .disclosureIndicator
@@ -346,8 +357,12 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 cell.accessoryType = .disclosureIndicator
             case "Sign-Up/Sign-In".localized():
                 cell.accessoryType = .disclosureIndicator
+                separatorLogin.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorLogin)
             case "Notification Message(s)".localized():
                 cell.accessoryType = .disclosureIndicator
+                separatorNotifPersonal.removeFromSuperview()
+                cell.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorNotifPersonal)
             case "Backup & Restore".localized():
                 cell.accessoryType = .disclosureIndicator
             case "Notification Message(s) Group".localized():
@@ -365,12 +380,19 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 accessoryButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
                 accessoryButton.contentMode = .scaleAspectFit
                 cell.accessoryView = accessoryButton as UIView
+                separatorVersion.removeFromSuperview()
+                cell.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorVersion)
             case "Vibrate Mode".localized():
                 cell.accessoryView = switchVibrateMode
             case "Save to Gallery".localized():
                 cell.accessoryView = switchSaveToGallery
             case "Auto Download".localized():
                 cell.accessoryView = switchAutoDownload
+                separatorAutoDownload.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorAutoDownload)
+            case "Sign-Out".localized():
+                separatorLogout.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorLogout)
             default:
                 content.secondaryText = nil
             }

+ 7 - 0
appbuilder-ios/NexilisLite/NexilisLite/Resource/id.lproj/Localizable.strings

@@ -273,3 +273,10 @@
 "3 months" = "3 bulan";
 "a week" = "seminggu";
 "Forever" = "selamanya";
+"Backup files are corrupted" = "File cadangan rusak";
+"Preparing..." = "Mempersiapkan...";
+"Uploading..." = "Mengunggah...";
+"Downloading..." = "Mengunduh...";
+"Restoring..." = "Memulihkan ...";
+"Successfully Restored Data" = "Berhasil Memulihkan Data";
+"Successfully Backup Data" = "Berhasil Mencadangkan Data";

+ 32 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Extension.swift

@@ -170,6 +170,38 @@ extension UIView {
         }
     }
     
+    public func addTopBorder(with color: UIColor?, andWidth borderWidth: CGFloat, view: UIView = UIView()) {
+        let border = view
+        border.backgroundColor = color
+        border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
+        border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: borderWidth)
+        addSubview(border)
+    }
+
+    public func addBottomBorder(with color: UIColor?, andWidth borderWidth: CGFloat, x: CGFloat = 0, view: UIView = UIView()) {
+        let border = view
+        border.backgroundColor = color
+        border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
+        border.frame = CGRect(x: x, y: frame.size.height - borderWidth, width: frame.size.width, height: borderWidth)
+        addSubview(border)
+    }
+
+    public func addLeftBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
+        let border = UIView()
+        border.backgroundColor = color
+        border.frame = CGRect(x: 0, y: 0, width: borderWidth, height: frame.size.height)
+        border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
+        addSubview(border)
+    }
+
+    public func addRightBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
+        let border = UIView()
+        border.backgroundColor = color
+        border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
+        border.frame = CGRect(x: frame.size.width - borderWidth, y: 0, width: borderWidth, height: frame.size.height)
+        addSubview(border)
+    }
+    
 }
 
 extension UIViewController {

+ 40 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -841,6 +841,46 @@ public class Nexilis: NSObject {
         }
     }
     
+    static var alertChangeProfile = UIAlertController()
+    public static func checkIsChangePerson() -> Bool {
+        let isChangeProfile = Utils.getSetProfile()
+        if !isChangeProfile {
+            alertChangeProfile.dismiss(animated: false)
+            alertChangeProfile = UIAlertController(title: "Change Profile".localized(), message: "You must change your name to use this feature".localized().localized(), preferredStyle: .alert)
+            alertChangeProfile.addAction(UIAlertAction(title: "Cancel".localized(), style: .destructive, handler: nil))
+            alertChangeProfile.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
+                let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
+                controller.forceLogin = true
+                let navigationController = UINavigationController(rootViewController: controller)
+                navigationController.modalPresentationStyle = .fullScreen
+                navigationController.navigationBar.tintColor = .white
+                navigationController.navigationBar.barTintColor = .mainColor
+                navigationController.navigationBar.isTranslucent = false
+                navigationController.navigationBar.overrideUserInterfaceStyle = .dark
+                navigationController.navigationBar.barStyle = .black
+                let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white]
+                UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
+                let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
+                navigationController.navigationBar.titleTextAttributes = textAttributes
+                navigationController.view.backgroundColor = .mainColor
+                let rootVC = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController
+                if rootVC?.presentedViewController == nil {
+                    rootVC?.present(navigationController, animated: true, completion: nil)
+                } else {
+                    rootVC?.presentedViewController?.present(navigationController, animated: true, completion: nil)
+                }
+            }))
+            let rootVC = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController
+            if rootVC?.presentedViewController == nil {
+                rootVC?.present(alertChangeProfile, animated: true, completion: nil)
+            } else {
+                rootVC?.presentedViewController?.present(alertChangeProfile, animated: true, completion: nil)
+            }
+            return false
+        }
+        return true
+    }
+    
     public static func showLoader() {
         loadingAlert = UIAlertController(title: nil, message: "Please wait...".localized(), preferredStyle: .alert)
 

+ 24 - 49
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BackupRestoreView.swift

@@ -34,6 +34,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
     var fileIdBackup = ""
     var recordSizeBackup = ""
     var optionBackup = ""
+    var recordSizeRestore: Int64 = 0
     
     let separator = String(unicodeCodepoint: 0x06) ?? ""
 
@@ -49,13 +50,15 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
         tableView.dataSource = self
         tableView.delegate = self
         
+        tableView.separatorStyle = .none
+        
         if #available(iOS 15.0, *) {
             tableView.sectionHeaderTopPadding = 0
         }
         
         
         let center: NotificationCenter = NotificationCenter.default
-        center.addObserver(self, selector: #selector(downloadFile(notification:)), name: NSNotification.Name(rawValue: "backupAvailability"), object: nil)
+        center.addObserver(self, selector: #selector(backupAvailability(notification:)), name: NSNotification.Name(rawValue: "backupAvailability"), object: nil)
         requestBackupAvailability()
     }
     
@@ -65,7 +68,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
         self.title = "Backup & Restore".localized()
     }
     
-    @objc private func downloadFile(notification: NSNotification) {
+    @objc private func backupAvailability(notification: NSNotification) {
         DispatchQueue.main.async { [self] in
             let data:[AnyHashable : Any] = notification.userInfo!
             if let message = data["message"] as? TMessage {
@@ -229,17 +232,14 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                         DispatchQueue.main.async { [self] in
                             guard progress == 100 else {
                                 labelRestoring.text = "Downloading...".localized() + "  \(progress)%"
-                                tableView.reloadSections(IndexSet(integer: 3), with: .none)
                                 return
                             }
                             labelRestoring.text = "Restoring...".localized()
-                            tableView.reloadSections(IndexSet(integer: 3), with: .none)
                             restoreData(file: fileURL, dirPath: dirPath, indexPath: indexPath)
                         }
                     }
                 } else {
                     labelRestoring.text = "Restoring...".localized()
-                    tableView.reloadSections(IndexSet(integer: 3), with: .none)
                     restoreData(file: fileURL, dirPath: dirPath, indexPath: indexPath)
                 }
             }
@@ -295,8 +295,6 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
         cell.contentView.subviews.forEach { $0.removeFromSuperview() }
         if indexPath.section == 0 {
             cell.selectionStyle = .none
-            cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: UIScreen.main.bounds.width)
-            
             let container = UIView()
             container.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
             container.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
@@ -355,6 +353,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
             if indexPath.row == 0 {
                 let container = UIView()
                 container.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
+                container.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 0.5, x: 10)
                 let content = cell.contentView
                 content.addSubview(container)
                 container.anchor(top: content.topAnchor, left: content.leftAnchor, bottom: content.bottomAnchor, right: content.rightAnchor)
@@ -380,8 +379,6 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                 titleChoosenOption.font = .systemFont(ofSize: 14)
                 
             } else {
-                cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: UIScreen.main.bounds.width)
-                
                 let container = UIView()
                 container.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
                 let content = cell.contentView
@@ -404,8 +401,6 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                 }
             }
         } else {
-            cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: UIScreen.main.bounds.width)
-            
             let container = UIView()
             container.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
             container.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1)
@@ -450,6 +445,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     }
                 }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "MESSAGE", cvalues: cValues, replace: true)
+                recordSizeRestore += 1
             } catch {
                 rollback.pointee = true
                 print(error)
@@ -465,6 +461,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     "message_id" : dataUcList[1],
                     "counter" : 0
                 ], replace: true)
+                recordSizeRestore += 1
             } catch {
                 rollback.pointee = true
                 print(error)
@@ -489,6 +486,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     }
                 }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "FORM_DATA", cvalues: cValues, replace: true)
+                recordSizeRestore += 1
             } catch {
                 rollback.pointee = true
                 print(error)
@@ -513,6 +511,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     }
                 }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "TASK_PIC", cvalues: cValues, replace: true)
+                recordSizeRestore += 1
             } catch {
                 rollback.pointee = true
                 print(error)
@@ -520,7 +519,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
         })
     }
     
-    private func restoreTasDetail(nameColumn: [String], data: [String]) {
+    private func restoreTaskDetail(nameColumn: [String], data: [String]) {
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             do {
                 var cValues: [String: Any] = [:]
@@ -537,6 +536,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     }
                 }
                 _ = try Database.shared.insertRecord(fmdb: fmdb, table: "TASK_DETAIL", cvalues: cValues, replace: true)
+                recordSizeRestore += 1
             } catch {
                 rollback.pointee = true
                 print(error)
@@ -545,6 +545,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
     }
     
     private func restoreData(file: URL, dirPath: String, indexPath: IndexPath) {
+        recordSizeRestore = 0
         let fileManager = FileManager()
         var destinationURL = URL(fileURLWithPath: dirPath)
         destinationURL.appendPathComponent("unzipItem\(Date().currentTimeMillis())")
@@ -583,17 +584,23 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                     let nameColumn = valueText[0].components(separatedBy: separator)
                     for i in 1..<valueText.count - 1 {
                         let dataTaskPIC = valueText[i].components(separatedBy: separator)
-                        restoreFormData(nameColumn: nameColumn, data: dataTaskPIC)
+                        restoreTaskPIC(nameColumn: nameColumn, data: dataTaskPIC)
                     }
                 }
                 else if nameFile.trimmingCharacters(in: .whitespacesAndNewlines) == "TASK_DETAIL" {
                     let nameColumn = valueText[0].components(separatedBy: separator)
                     for i in 1..<valueText.count - 1 {
                         let dataTaskDetail = valueText[i].components(separatedBy: separator)
-                        restoreFormData(nameColumn: nameColumn, data: dataTaskDetail)
+                        restoreTaskDetail(nameColumn: nameColumn, data: dataTaskDetail)
                     }
                 }
             }
+            if recordSizeRestore < Int64(recordSizeBackup) ?? 0 {
+                labelRestoring.text = "Backup files are corrupted".localized()
+                tableView.reloadSections(IndexSet(integer: 3), with: .none)
+            } else {
+                labelRestoring.text = "Successfully Restored Data".localized()
+            }
             DispatchQueue.global().async { [self] in
                 _ = Nexilis.write(message: CoreMessage_TMessageBank.getBackupRestored(option: optionBackup, fileid: fileIdBackup))
             }
@@ -608,7 +615,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
             })
         } catch {
             print(error)
-            self.view.makeToast("\(error)", duration: 0.5)
+            self.view.makeToast("Backup files are corrupted".localized(), duration: 0.5)
             DispatchQueue.global().async { [self] in
                 _ = Nexilis.write(message: CoreMessage_TMessageBank.getBackupRestored(option: optionBackup, fileid: fileIdBackup))
             }
@@ -861,6 +868,8 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                                     
                                     valueLastBackup = dayLastBackup.localized() + ", " + timeLastBackup
                                     valuesizeBackup = Units(bytes: fileSize).getReadableUnit()
+                                    
+                                    labelPreparing.text = "Successfully Backup Data".localized()
                                     DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: { [self] in
                                         isBackupStart = false
                                         tableView.beginUpdates()
@@ -879,40 +888,6 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
 
 }
 
-extension UIView {
-    func addTopBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
-        let border = UIView()
-        border.backgroundColor = color
-        border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
-        border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: borderWidth)
-        addSubview(border)
-    }
-
-    func addBottomBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
-        let border = UIView()
-        border.backgroundColor = color
-        border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
-        border.frame = CGRect(x: 0, y: frame.size.height - borderWidth, width: frame.size.width, height: borderWidth)
-        addSubview(border)
-    }
-
-    func addLeftBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
-        let border = UIView()
-        border.backgroundColor = color
-        border.frame = CGRect(x: 0, y: 0, width: borderWidth, height: frame.size.height)
-        border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
-        addSubview(border)
-    }
-
-    func addRightBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
-        let border = UIView()
-        border.backgroundColor = color
-        border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
-        border.frame = CGRect(x: frame.size.width - borderWidth, y: 0, width: borderWidth, height: frame.size.height)
-        addSubview(border)
-    }
-}
-
 extension String {
     func appendLineToURL(fileURL: URL) throws {
          try (self + "\n").appendToURL(fileURL: fileURL)

+ 38 - 48
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift

@@ -20,6 +20,12 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     var switchSaveToGallery = UISwitch()
     var switchAutoDownload = UISwitch()
     
+    let separatorLogout = UIView()
+    let separatorNotifPersonal = UIView()
+    let separatorAutoDownload = UIView()
+    let separatorVersion = UIView()
+    let separatorLogin = UIView()
+    
     var notInTab = false
     
     public override func viewDidLoad() {
@@ -27,7 +33,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
         
         tableView.delegate = self
         tableView.dataSource = self
-        tableView.layoutMargins = .init(top: 0, left: 5, bottom: 0, right: 5)
+        tableView.layoutMargins = .init(top: 0, left: 0, bottom: 0, right: 0)
 //        tableView.separatorColor = .gray
         tableView.separatorStyle = .none
         
@@ -102,28 +108,28 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 }
                 if ( User.isInternal(userType: cursorUser.string(forColumnIndex: 0) ?? "") && position == "1") || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") {
                     Item.menus["Personal"] = [
-                        Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
+                        Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                         Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
                         Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized()),
                         Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Sign-In to Web".localized()),
                     ]
                 } else if User.isInternal(userType: cursorUser.string(forColumnIndex: 0) ?? "") || User.isCallCenter(userType: cursorUser.string(forColumnIndex: 0) ?? "") || User.isVerified(official_account: cursorUser.string(forColumnIndex: 2) ?? "") {
                     Item.menus["Personal"] = [
-                        Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
+                        Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                         Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
                         Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Sign-In to Web".localized()),
                     ]
                 } else {
                     Item.menus["Personal"] = [
-                        Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
+                        Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                             Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
-                        Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Access Admin / Internal Features".localized()),
+                        Item(icon: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Access Admin / Internal Features".localized()),
                     ]
                 }
                 if !isChangeProfile {
                     Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Sign-Up/Sign-In".localized()))
                 } else if isChangeProfile {
-                    Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.counterclockwise.icloud.fill"), title: "Backup & Restore".localized()))
+                    Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.clockwise.icloud"), title: "Backup & Restore".localized()))
                     Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Sign-Out".localized()))
                 }
                 let image = cursorUser.string(forColumnIndex: 1)
@@ -164,9 +170,9 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 cursorUser.close()
             } else {
                 Item.menus["Personal"] = [
-                    Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
+                    Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                         Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
-                    Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Access Admin / Internal Features".localized()),
+                    Item(icon: UIImage(named: ""), title: "Access Admin / Internal Features".localized()),
                     Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Sign-Up/Sign-In".localized())
                 ]
                 if !imageSignIn.isEmpty {
@@ -252,6 +258,12 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     
     public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
+        let isChangeProfile = Utils.getSetProfile()
+        if !isChangeProfile {
+            separatorLogout.removeFromSuperview()
+        } else {
+            separatorLogin.removeFromSuperview()
+        }
         cell.accessoryType = .none
         cell.indentationLevel = 0
         var content = cell.defaultContentConfiguration()
@@ -267,7 +279,6 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
             content.imageProperties.maximumSize = CGSize(width: 24, height: 24)
             content.text = menu.title
             cell.accessoryView = nil
-            cell.separatorInset = UIEdgeInsets(top: .greatestFiniteMagnitude, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
             switch menu.title {
             case "Personal Information".localized():
                 cell.accessoryType = .disclosureIndicator
@@ -277,10 +288,14 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 cell.accessoryType = .disclosureIndicator
             case "Sign-Up/Sign-In".localized():
                 cell.accessoryType = .disclosureIndicator
-            case "Backup & Restore".localized():
-                cell.accessoryType = .disclosureIndicator
+                separatorLogin.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorLogin)
             case "Notification Message(s)".localized():
                 cell.accessoryType = .disclosureIndicator
+                separatorNotifPersonal.removeFromSuperview()
+                cell.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorNotifPersonal)
+            case "Backup & Restore".localized():
+                cell.accessoryType = .disclosureIndicator
             case "Notification Message(s) Group".localized():
                 cell.accessoryType = .disclosureIndicator
 //            case "Logout".localized():
@@ -296,12 +311,19 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 accessoryButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
                 accessoryButton.contentMode = .scaleAspectFit
                 cell.accessoryView = accessoryButton as UIView
+                separatorVersion.removeFromSuperview()
+                cell.addTopBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorVersion)
             case "Vibrate Mode".localized():
                 cell.accessoryView = switchVibrateMode
             case "Save to Gallery".localized():
                 cell.accessoryView = switchSaveToGallery
             case "Auto Download".localized():
                 cell.accessoryView = switchAutoDownload
+                separatorAutoDownload.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorAutoDownload)
+            case "Sign-Out".localized():
+                separatorLogout.removeFromSuperview()
+                cell.addBottomBorder(with: .lightGray.withAlphaComponent(0.5), andWidth: 1, view: separatorLogout)
             default:
                 content.secondaryText = nil
             }
@@ -310,45 +332,10 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
         return cell
     }
     
-    private func checkIsChangePerson() -> Bool {
-        let isChangeProfile = Utils.getSetProfile()
-        if !isChangeProfile {
-            let alert = UIAlertController(title: "Change Profile".localized(), message: "You must change your name to use this feature".localized(), preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
-                let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
-                controller.forceLogin = true
-                let navigationController = UINavigationController(rootViewController: controller)
-                navigationController.modalPresentationStyle = .fullScreen
-                navigationController.navigationBar.tintColor = .white
-                navigationController.navigationBar.barTintColor = .mainColor
-                navigationController.navigationBar.isTranslucent = false
-                navigationController.navigationBar.overrideUserInterfaceStyle = .dark
-                navigationController.navigationBar.barStyle = .black
-                let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white]
-                UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
-                let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
-                navigationController.navigationBar.titleTextAttributes = textAttributes
-                navigationController.view.backgroundColor = .mainColor
-                if UIApplication.shared.visibleViewController?.navigationController != nil {
-                    UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
-                } else {
-                    UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
-                }
-            }))
-            if UIApplication.shared.visibleViewController?.navigationController != nil {
-                UIApplication.shared.visibleViewController?.navigationController?.present(alert, animated: true, completion: nil)
-            } else {
-                UIApplication.shared.visibleViewController?.present(alert, animated: true, completion: nil)
-            }
-            return false
-        }
-        return true
-    }
-    
     public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         let item = Item.menuFor(section: indexPath.section)[indexPath.row]
         if item.title == "Personal Information".localized() {
-            if(checkIsChangePerson()){
+            if(Nexilis.checkIsChangePerson()){
                 let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
                 controller.data = UserDefaults.standard.string(forKey: "me")!
                 controller.flag = .me
@@ -362,7 +349,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 navigationController?.show(controller, sender: nil)
             }
         } else if item.title == "Access Admin / Internal Features".localized() || item.title == "Change Admin / Internal Password".localized() {
-            if(checkIsChangePerson()){
+            if(Nexilis.checkIsChangePerson()){
                 if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
                     let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                     imageView.tintColor = .white
@@ -566,6 +553,9 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
             navigationController.navigationBar.titleTextAttributes = textAttributes
             navigationController.view.backgroundColor = .mainColor
             self.present(navigationController, animated: true)
+        } else if item.title == "Backup & Restore".localized() {
+            let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "backupRestore") as! BackupRestoreView
+            navigationController?.show(controller, sender: nil)
         }
     }