alqindiirsyam il y a 2 ans
Parent
commit
1dff08acaa

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

@@ -162,6 +162,8 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                         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()),
+                        Item(icon: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Set Internal Account".localized()),
+                        Item(icon: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Set CS Account".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"] = [
@@ -173,7 +175,7 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                     Item.menus["Personal"] = [
                         Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                             Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
-                        Item(icon: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Access Admin / Internal Features".localized()),
+                        Item(icon: UIImage(systemName: "person.badge.key"), title: "Access Admin / Internal Features".localized()),
                     ]
                 }
                 if !isChangeProfile {
@@ -222,7 +224,7 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 Item.menus["Personal"] = [
                     Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
                         Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
-                    Item(icon: UIImage(named: ""), title: "Access Admin / Internal Features".localized()),
+                    Item(icon: UIImage(systemName: "person.badge.key"), 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 {
@@ -372,6 +374,10 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 cell.accessoryType = .disclosureIndicator
             case "Change Language".localized():
                 cell.accessoryType = .disclosureIndicator
+            case "Set Internal Account".localized():
+                cell.accessoryType = .disclosureIndicator
+            case "Set CS Account".localized():
+                cell.accessoryType = .disclosureIndicator
             case "Version".localized():
                 let accessoryButton = UIButton(type: .custom)
                 accessoryButton.setTitle(UIApplication.appVersion, for: .normal)
@@ -657,6 +663,13 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
         } else if item.title == "Backup & Restore".localized() {
             let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "backupRestore") as! BackupRestoreView
             navigationController?.show(controller, sender: nil)
+        } else if item.title == "Set Internal Account".localized() {
+            let controller = SetInternalCSAccount()
+            navigationController?.show(controller, sender: nil)
+        } else if item.title == "Set CS Account".localized() {
+            let controller = SetInternalCSAccount()
+            controller.isSetCS = true
+            navigationController?.show(controller, sender: nil)
         }
     }
     

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

@@ -280,3 +280,12 @@
 "Restoring..." = "Memulihkan ...";
 "Successfully Restored Data" = "Berhasil Memulihkan Data";
 "Successfully Backup Data" = "Berhasil Mencadangkan Data";
+"Set Internal Account" = "Atur Akun Internal";
+"Set CS Account" = "Atur Akun CS";
+"Are you sure want to set" = "Apakah anda ingin mengatur";
+"become CS Account?" = "menjadi Akun CS";
+"become Internal Account?" = "menjadi Akun Internal";
+"Are you sure want to unset" = "Apakah anda ingin menghapus";
+"from CS Account?" = "dari Akun CS";
+"from Internal Account?" = "dari Akun Internal";
+

+ 20 - 17
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -505,26 +505,29 @@ public class ProfileViewController: UITableViewController {
         if isLoadingAddFriend {
             return
         }
+        Nexilis.showLoader()
         isLoadingAddFriend = true
         addFriend { result in
-            DispatchQueue.main.async { [self] in
-                if result {
-                    let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                    imageView.tintColor = .white
-                    publicBanner.dismiss()
-                    publicBanner = FloatingNotificationBanner(title: "Successfully add friend".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
-                    publicBanner.show()
-                    self.isDismiss?()
-                    self.navigationController?.popViewController(animated: true)
-                } else {
-                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                    imageView.tintColor = .white
-                    publicBanner.dismiss()
-                    publicBanner = FloatingNotificationBanner(title: "Server busy, please try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                    publicBanner.show()
-                    self.isLoadingAddFriend = false
+            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
+                Nexilis.hideLoader { [self] in
+                    if result {
+                        let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                        imageView.tintColor = .white
+                        publicBanner.dismiss()
+                        publicBanner = FloatingNotificationBanner(title: "Successfully add friend".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
+                        publicBanner.show()
+                        self.isDismiss?()
+                        self.navigationController?.popViewController(animated: true)
+                    } else {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        publicBanner.dismiss()
+                        publicBanner = FloatingNotificationBanner(title: "Server busy, please try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                        publicBanner.show()
+                        self.isLoadingAddFriend = false
+                    }
                 }
-            }
+            })
         }
     }
     

+ 266 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SetInternalCSAccount.swift

@@ -0,0 +1,266 @@
+//
+//  SetInternalAccount.swift
+//  NexilisLite
+//
+//  Created by Akhmad Al Qindi Irsyam on 23/02/23.
+//
+
+import UIKit
+import NotificationBannerSwift
+
+public class SetInternalCSAccount: UITableViewController {
+    private var searchController: UISearchController!
+    public var isSetCS = false
+    
+    private var availableUser: [User] = []
+    
+    private var fillteredUser: [User] = []
+    
+    private var isSearchBarEmpty: Bool {
+        return searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
+    }
+    
+    private var isFilltering: Bool {
+        return searchController.isActive && !isSearchBarEmpty
+    }
+    
+    public override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        navigationController?.navigationBar.topItem?.backButtonTitle = "Back".localized()
+        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellCSInternal")
+        
+        searchController = UISearchController(searchResultsController: nil)
+        searchController.delegate = self
+        searchController.searchResultsUpdater = self
+        searchController.searchBar.autocapitalizationType = .none
+        searchController.searchBar.delegate = self
+        searchController.searchBar.barTintColor = .secondaryColor
+        searchController.searchBar.searchTextField.backgroundColor = .secondaryColor
+        searchController.obscuresBackgroundDuringPresentation = false
+        
+        definesPresentationContext = true
+        
+        navigationItem.searchController = searchController
+        navigationItem.hidesSearchBarWhenScrolling = true
+        
+        if #available(iOS 15.0, *) {
+            tableView.sectionHeaderTopPadding = 0
+        }
+        
+        getData { users in
+            self.availableUser.append(contentsOf: users)
+            DispatchQueue.main.async {
+                self.tableView.reloadData()
+            }
+        }
+    }
+    
+    public override func viewDidAppear(_ animated: Bool) {
+        self.navigationController?.navigationBar.topItem?.title = "Backup & Restore".localized()
+        self.navigationController?.navigationBar.setNeedsLayout()
+        self.title = isSetCS ? "Set CS Account".localized()  :"Set Internal Account".localized()
+    }
+    
+    func getData(completion: @escaping ([User]) -> ()) {
+        DispatchQueue.global().async {
+            Database.shared.database?.inTransaction({ (fmdb, rollback) in
+                var r: [User] = []
+                var query =  "SELECT u.f_pin, u.first_name, u.last_name, u.image_id, u.user_type FROM BUDDY u where u.f_pin <> '\(User.getMyPin()!)' and u.user_type <> '24' and u.official_account <> '1' and u.official_account <> '2' and u.official_account <> '3' UNION SELECT m.f_pin, m.first_name, m.last_name, m.thumb_id, '23' as user_type FROM GROUPZ_MEMBER m where group_id = (select g.group_id from GROUPZ g where g.official = 1 and g.level = 2) and m.position <> '1' order by 2 collate nocase asc"
+                if self.isSetCS {
+                    query =  "SELECT u.f_pin, u.first_name, u.last_name, u.image_id, u.user_type FROM BUDDY u where u.f_pin <> '\(User.getMyPin()!)' and u.official_account <> '1' and u.official_account <> '2' and u.official_account <> '3' UNION SELECT m.f_pin, m.first_name, m.last_name, m.thumb_id, '24' as user_type FROM GROUPZ_MEMBER m where group_id = (select g.group_id from GROUPZ g where g.official = 1 and g.level = 3) and m.position <> '1' order by 2 collate nocase asc"
+                }
+                if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: query) {
+                    while cursorData.next() {
+                        let user = User(pin: cursorData.string(forColumnIndex: 0) ?? "",
+                                            firstName: cursorData.string(forColumnIndex: 1) ?? "",
+                                            lastName: cursorData.string(forColumnIndex: 2) ?? "",
+                                            thumb: cursorData.string(forColumnIndex: 3) ?? "",
+                                            userType: cursorData.string(forColumnIndex: 4) ?? "")
+                        if (user.firstName + " " + user.lastName).trimmingCharacters(in: .whitespaces) == "USR\(user.pin)" {
+                            continue
+                        }
+                        print("WEW <> \(cursorData.string(forColumnIndex: 1)!) <> \(cursorData.string(forColumnIndex: 4)!)")
+                        r.append(user)
+                    }
+                    cursorData.close()
+                }
+                completion(r)
+            })
+        }
+    }
+    
+    private func setInternalCS(user: User) {
+        let alert = UIAlertController(title: "", message: "Are you sure want to set".localized() + " \(user.fullName) " + (isSetCS ? "become CS Account?".localized() : "become Internal Account?".localized()), preferredStyle: .alert)
+        alert.addAction(UIAlertAction(title: "No".localized(), style: .default, handler: nil))
+        alert.addAction(UIAlertAction(title: "Yes".localized(), style: .default, handler: {(_) in
+            Nexilis.showLoader()
+            Database.shared.database?.inTransaction({ fmdb, rollback in
+                if let result = Nexilis.writeSync(message: CoreMessage_TMessageBank.getManagementContactCenter(user_type: (self.isSetCS ? "1" : "3"), l_pin: user.pin), timeout: 5000) {
+                    if result.isOk() {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
+                            let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Successfully changed".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
+                            banner.show()
+                            self.getData { users in
+                                self.availableUser.removeAll()
+                                self.availableUser.append(contentsOf: users)
+                                DispatchQueue.main.async {
+                                    self.tableView.reloadData()
+                                }
+                            }
+                            Nexilis.hideLoader {}
+                        })
+                    } else {
+                        DispatchQueue.main.async {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
+                            banner.show()
+                            Nexilis.hideLoader {}
+                        }
+                    }
+                } else {
+                    DispatchQueue.main.async {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
+                        banner.show()
+                    }
+                }
+            })
+        }))
+        self.present(alert, animated: true, completion: nil)
+    }
+    
+    private func unsetInternalCS(user: User) {
+        let alert = UIAlertController(title: "", message: "Are you sure want to unset".localized() + " \(user.fullName) " + (isSetCS ? "from CS Account?".localized() : "from Internal Account?".localized()), preferredStyle: .alert)
+        alert.addAction(UIAlertAction(title: "No".localized(), style: UIAlertAction.Style.default, handler: nil))
+        alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
+            Nexilis.showLoader()
+            Database.shared.database?.inTransaction({ fmdb, rollback in
+                if let result = Nexilis.writeSync(message: CoreMessage_TMessageBank.getManagementContactCenter(user_type: (self.isSetCS ? "0" : "2"), l_pin: user.pin), timeout: 5000) {
+                    if result.isOk() {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
+                            let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Successfully changed".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
+                            banner.show()
+                            self.getData { users in
+                                self.availableUser.removeAll()
+                                self.availableUser.append(contentsOf: users)
+                                DispatchQueue.main.async {
+                                    self.tableView.reloadData()
+                                }
+                            }
+                            Nexilis.hideLoader {}
+                        })
+                    } else {
+                        DispatchQueue.main.async {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
+                            banner.show()
+                            Nexilis.hideLoader {}
+                        }
+                    }
+                } else {
+                    DispatchQueue.main.async {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
+                        banner.show()
+                    }
+                }
+            })
+        }))
+        self.present(alert, animated: true, completion: nil)
+    }
+    
+    func filterContentForSearchText(_ searchText: String) {
+        fillteredUser = availableUser.filter({ d in
+            let name = "\(d.firstName) \(d.lastName)".trimmingCharacters(in: .whitespaces)
+            return name.lowercased().contains(searchText.lowercased())
+        })
+        tableView.reloadData()
+    }
+
+    // MARK: - Table view data source
+
+    public override func numberOfSections(in tableView: UITableView) -> Int {
+        return 1
+    }
+
+    public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return availableUser.count
+    }
+    
+    public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let cell = tableView.dequeueReusableCell(withIdentifier: "cellCSInternal", for: indexPath as IndexPath)
+        var content = cell.defaultContentConfiguration()
+        let user: User
+        if isFilltering {
+            user = fillteredUser[indexPath.row]
+        } else {
+            user = availableUser[indexPath.row]
+        }
+        content.imageProperties.maximumSize = CGSize(width: 40, height: 40)
+        getImage(name: user.thumb, placeholderImage: UIImage(named: "Profile---Purple", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), isCircle: true, tableView: tableView, indexPath: indexPath) { result, isDownloaded, image in
+            content.image = image
+            if !result {
+                content.imageProperties.tintColor = .mainColor
+            }
+        }
+        if user.userType == "23" {
+            content.attributedText = self.set(image: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " " + (user.firstName + " " + user.lastName).trimmingCharacters(in: .whitespaces), size: 15, y: -4)
+        } else if user.userType == "24" {
+            content.attributedText = self.set(image: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " " + (user.firstName + " " + user.lastName).trimmingCharacters(in: .whitespaces), size: 15, y: -4)
+        } else {
+            content.text = (user.firstName + " " + user.lastName).trimmingCharacters(in: .whitespaces)
+        }
+        cell.contentConfiguration = content
+        cell.accessoryType = user.isSelected ? .checkmark : .none
+        return cell
+    }
+    
+    public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        tableView.deselectRow(at: indexPath, animated: true)
+        let user: User
+        if isFilltering {
+            user = fillteredUser[indexPath.row]
+        } else {
+            user = availableUser[indexPath.row]
+        }
+        if User.isCallCenter(userType: user.userType!) || (User.isInternal(userType: user.userType!) && !isSetCS) {
+            unsetInternalCS(user: user)
+        } else {
+            setInternalCS(user: user)
+        }
+    }
+}
+
+extension SetInternalCSAccount: UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
+    
+    public func updateSearchResults(for searchController: UISearchController) {
+        filterContentForSearchText(searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines))
+    }
+    
+    func set(image: UIImage, with text: String, size: CGFloat, y: CGFloat, colorText: UIColor = UIColor.black) -> NSAttributedString {
+        let attachment = NSTextAttachment()
+        attachment.image = image
+        attachment.bounds = CGRect(x: 0, y: y, width: size, height: size)
+        let attachmentStr = NSAttributedString(attachment: attachment)
+        
+        let mutableAttributedString = NSMutableAttributedString()
+        mutableAttributedString.append(attachmentStr)
+        
+        let attributedStringColor = [NSAttributedString.Key.foregroundColor : colorText]
+        let textString = NSAttributedString(string: text, attributes: attributedStringColor)
+        mutableAttributedString.append(textString)
+        
+        
+        return mutableAttributedString
+    }
+    
+}