diff --git a/TraccarClient.xcodeproj/project.pbxproj b/TraccarClient.xcodeproj/project.pbxproj
index f57835edeb6b4c0b30f3cae68bd9806b507bf426..2f1574112a659ec574b01779120ed09d6b9a56e3 100644
--- a/TraccarClient.xcodeproj/project.pbxproj
+++ b/TraccarClient.xcodeproj/project.pbxproj
@@ -64,6 +64,12 @@
 		532683B12AE94C9400A364C0 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683B02AE94C9400A364C0 /* Dictionary.swift */; };
 		532683B32AE98D0000A364C0 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683B22AE98D0000A364C0 /* UILabel.swift */; };
 		532683B52AE98FB600A364C0 /* UIString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683B42AE98FB600A364C0 /* UIString.swift */; };
+		532683BB2AEA50B800A364C0 /* LoginDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683BA2AEA50B800A364C0 /* LoginDataSource.swift */; };
+		532683BD2AEA50C600A364C0 /* LoginModelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683BC2AEA50C600A364C0 /* LoginModelController.swift */; };
+		532683BF2AEA50EF00A364C0 /* LoginDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683BE2AEA50EF00A364C0 /* LoginDataProvider.swift */; };
+		532683C12AEA50FA00A364C0 /* LoginViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683C02AEA50FA00A364C0 /* LoginViewControllerProtocol.swift */; };
+		532683C32AEA537F00A364C0 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532683C22AEA537F00A364C0 /* UITableView.swift */; };
+		532683C82AEA631800A364C0 /* IQKeyboardManagerSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 532683C72AEA631800A364C0 /* IQKeyboardManagerSwift */; };
 		5E394EBE28A9CC7600396F33 /* BatteryStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E394EBD28A9CC7600396F33 /* BatteryStatus.swift */; };
 		5E716A271F63A0B100A2DBC3 /* DistanceCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A261F63A0B100A2DBC3 /* DistanceCalculator.swift */; };
 		5E716A291F63A45A00A2DBC3 /* RequestManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A281F63A45A00A2DBC3 /* RequestManager.swift */; };
@@ -177,6 +183,11 @@
 		532683B02AE94C9400A364C0 /* Dictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
 		532683B22AE98D0000A364C0 /* UILabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
 		532683B42AE98FB600A364C0 /* UIString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIString.swift; sourceTree = "<group>"; };
+		532683BA2AEA50B800A364C0 /* LoginDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDataSource.swift; sourceTree = "<group>"; };
+		532683BC2AEA50C600A364C0 /* LoginModelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginModelController.swift; sourceTree = "<group>"; };
+		532683BE2AEA50EF00A364C0 /* LoginDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDataProvider.swift; sourceTree = "<group>"; };
+		532683C02AEA50FA00A364C0 /* LoginViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewControllerProtocol.swift; sourceTree = "<group>"; };
+		532683C22AEA537F00A364C0 /* UITableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
 		5E394EBD28A9CC7600396F33 /* BatteryStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryStatus.swift; sourceTree = "<group>"; };
 		5E716A261F63A0B100A2DBC3 /* DistanceCalculator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DistanceCalculator.swift; sourceTree = "<group>"; };
 		5E716A281F63A45A00A2DBC3 /* RequestManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestManager.swift; sourceTree = "<group>"; };
@@ -252,6 +263,7 @@
 				532683812AE923DE00A364C0 /* Alamofire in Frameworks */,
 				CED4871C17DB1BF6007FCF57 /* UIKit.framework in Frameworks */,
 				5EE3CA362998948F002C86E4 /* FirebaseCrashlytics in Frameworks */,
+				532683C82AEA631800A364C0 /* IQKeyboardManagerSwift in Frameworks */,
 				5EE3CA39299894B9002C86E4 /* InAppSettingsKit in Frameworks */,
 				CED4871E17DB1BF6007FCF57 /* Foundation.framework in Frameworks */,
 				CED4872017DB1BF6007FCF57 /* CoreGraphics.framework in Frameworks */,
@@ -271,11 +283,9 @@
 		532683392AE9174700A364C0 /* Views */ = {
 			isa = PBXGroup;
 			children = (
-				532683822AE928F900A364C0 /* KNTableViewCell.swift */,
-				532683662AE923A500A364C0 /* BMTextFieldView */,
-				5326833A2AE9175900A364C0 /* LoginViewController.swift */,
-				5326833B2AE9175900A364C0 /* LoginViewController.xib */,
-				532683842AE9293200A364C0 /* KNComponentView.swift */,
+				532683C52AEA5DDF00A364C0 /* Custom */,
+				CED4873317DB1BF6007FCF57 /* MainStoryboard.storyboard */,
+				CEF643241B919FFA00195CEA /* LaunchScreen.xib */,
 			);
 			name = Views;
 			sourceTree = "<group>";
@@ -322,6 +332,7 @@
 				532683AE2AE94C2F00A364C0 /* NSLayoutConstraints.swift */,
 				532683B02AE94C9400A364C0 /* Dictionary.swift */,
 				532683B22AE98D0000A364C0 /* UILabel.swift */,
+				532683C22AEA537F00A364C0 /* UITableView.swift */,
 			);
 			name = helpers;
 			sourceTree = "<group>";
@@ -376,6 +387,61 @@
 			name = Network;
 			sourceTree = "<group>";
 		};
+		532683B62AEA505C00A364C0 /* LoginViewController */ = {
+			isa = PBXGroup;
+			children = (
+				532683B92AEA508300A364C0 /* Controller */,
+				532683B82AEA507900A364C0 /* View */,
+				532683B72AEA507300A364C0 /* Model */,
+			);
+			path = LoginViewController;
+			sourceTree = "<group>";
+		};
+		532683B72AEA507300A364C0 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				532683BA2AEA50B800A364C0 /* LoginDataSource.swift */,
+				532683BC2AEA50C600A364C0 /* LoginModelController.swift */,
+				532683BE2AEA50EF00A364C0 /* LoginDataProvider.swift */,
+				532683C02AEA50FA00A364C0 /* LoginViewControllerProtocol.swift */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		532683B82AEA507900A364C0 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				5326833B2AE9175900A364C0 /* LoginViewController.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		532683B92AEA508300A364C0 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				5326833A2AE9175900A364C0 /* LoginViewController.swift */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		532683C42AEA5DB000A364C0 /* Controllers */ = {
+			isa = PBXGroup;
+			children = (
+				532683B62AEA505C00A364C0 /* LoginViewController */,
+			);
+			name = Controllers;
+			sourceTree = "<group>";
+		};
+		532683C52AEA5DDF00A364C0 /* Custom */ = {
+			isa = PBXGroup;
+			children = (
+				532683842AE9293200A364C0 /* KNComponentView.swift */,
+				532683822AE928F900A364C0 /* KNTableViewCell.swift */,
+				532683662AE923A500A364C0 /* BMTextFieldView */,
+			);
+			path = Custom;
+			sourceTree = "<group>";
+		};
 		CED4870F17DB1BF6007FCF57 = {
 			isa = PBXGroup;
 			children = (
@@ -412,14 +478,13 @@
 		CED4872117DB1BF6007FCF57 /* TraccarClient */ = {
 			isa = PBXGroup;
 			children = (
+				CB7ED0831F662BAF00A33FCF /* AppDelegate.swift */,
+				532683C42AEA5DB000A364C0 /* Controllers */,
 				532683632AE91CAC00A364C0 /* helpers */,
 				CE5899C71B115C9100ED70D2 /* Images.xcassets */,
-				CED4873317DB1BF6007FCF57 /* MainStoryboard.storyboard */,
-				CEF643241B919FFA00195CEA /* LaunchScreen.xib */,
 				CEF643371B91A94600195CEA /* Localizable.strings */,
 				532683392AE9174700A364C0 /* Views */,
 				CED4872217DB1BF6007FCF57 /* Supporting Files */,
-				CB7ED0831F662BAF00A33FCF /* AppDelegate.swift */,
 				CB4197921F674A3E008F301C /* DatabaseHelper.swift */,
 				5E716A261F63A0B100A2DBC3 /* DistanceCalculator.swift */,
 				CBAA0F7E1F68E807008BBBBE /* MainViewController.swift */,
@@ -491,6 +556,7 @@
 				5EE3CA38299894B9002C86E4 /* InAppSettingsKit */,
 				532683802AE923DE00A364C0 /* Alamofire */,
 				5326839E2AE9489C00A364C0 /* Reachability */,
+				532683C72AEA631800A364C0 /* IQKeyboardManagerSwift */,
 			);
 			productName = TraccarClient;
 			productReference = CED4871817DB1BF6007FCF57 /* TraccarClient.app */;
@@ -559,6 +625,7 @@
 				5EE3CA37299894B9002C86E4 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */,
 				5326837F2AE923DE00A364C0 /* XCRemoteSwiftPackageReference "Alamofire" */,
 				5326839D2AE9489C00A364C0 /* XCRemoteSwiftPackageReference "Reachability" */,
+				532683C62AEA631800A364C0 /* XCRemoteSwiftPackageReference "IQKeyboardManager" */,
 			);
 			productRefGroup = CED4871917DB1BF6007FCF57 /* Products */;
 			projectDirPath = "";
@@ -640,6 +707,7 @@
 				532683962AE9482300A364C0 /* Network+Endpoint.swift in Sources */,
 				CB7ED0801F6602CD00A33FCF /* Position.swift in Sources */,
 				532683972AE9482300A364C0 /* Network+Result.swift in Sources */,
+				532683BB2AEA50B800A364C0 /* LoginDataSource.swift in Sources */,
 				5326837A2AE923A500A364C0 /* KNFieldDropDownAddressObjectProtocol.swift in Sources */,
 				CBAA0F7F1F68E807008BBBBE /* MainViewController.swift in Sources */,
 				532683B52AE98FB600A364C0 /* UIString.swift in Sources */,
@@ -668,6 +736,7 @@
 				CBAA0F7D1F68E14C008BBBBE /* StatusViewController.swift in Sources */,
 				532683A72AE94ADC00A364C0 /* KNObject.swift in Sources */,
 				532683A12AE948FF00A364C0 /* AppManager.swift in Sources */,
+				532683C12AEA50FA00A364C0 /* LoginViewControllerProtocol.swift in Sources */,
 				532683A32AE9497100A364C0 /* Keys.swift in Sources */,
 				532683A92AE94B1300A364C0 /* UIInt.swift in Sources */,
 				5326837D2AE923A500A364C0 /* KNFieldBuilder.swift in Sources */,
@@ -677,10 +746,13 @@
 				5E716A271F63A0B100A2DBC3 /* DistanceCalculator.swift in Sources */,
 				532683792AE923A500A364C0 /* FieldTableViewCell.swift in Sources */,
 				5326838B2AE92CA500A364C0 /* JSONField.swift in Sources */,
+				532683BF2AEA50EF00A364C0 /* LoginDataProvider.swift in Sources */,
 				532683892AE92B6800A364C0 /* Observable.swift in Sources */,
+				532683BD2AEA50C600A364C0 /* LoginModelController.swift in Sources */,
 				5326837B2AE923A500A364C0 /* KNFieldType.swift in Sources */,
 				532683B12AE94C9400A364C0 /* Dictionary.swift in Sources */,
 				5E716A291F63A45A00A2DBC3 /* RequestManager.swift in Sources */,
+				532683C32AEA537F00A364C0 /* UITableView.swift in Sources */,
 				5326839B2AE9482300A364C0 /* NetworkRequest.swift in Sources */,
 				CB4197931F674A3E008F301C /* DatabaseHelper.swift in Sources */,
 			);
@@ -1167,6 +1239,14 @@
 				kind = branch;
 			};
 		};
+		532683C62AEA631800A364C0 /* XCRemoteSwiftPackageReference "IQKeyboardManager" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/hackiftekhar/IQKeyboardManager";
+			requirement = {
+				kind = upToNextMajorVersion;
+				minimumVersion = 6.5.16;
+			};
+		};
 		5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
 			isa = XCRemoteSwiftPackageReference;
 			repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
@@ -1196,6 +1276,11 @@
 			package = 5326839D2AE9489C00A364C0 /* XCRemoteSwiftPackageReference "Reachability" */;
 			productName = Reachability;
 		};
+		532683C72AEA631800A364C0 /* IQKeyboardManagerSwift */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 532683C62AEA631800A364C0 /* XCRemoteSwiftPackageReference "IQKeyboardManager" */;
+			productName = IQKeyboardManagerSwift;
+		};
 		5EE3CA332998948F002C86E4 /* FirebaseAnalytics */ = {
 			isa = XCSwiftPackageProductDependency;
 			package = 5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index d5843b2df106c54f5924be5431ba7da11dc596b9..c2746fdab1021ccf7053be9a7e6e8c138e119a8c 100644
--- a/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -90,6 +90,15 @@
         "revision" : "08ab93cd15759eed534b821c2ea789d97a0fdca0"
       }
     },
+    {
+      "identity" : "iqkeyboardmanager",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/hackiftekhar/IQKeyboardManager",
+      "state" : {
+        "revision" : "c00b1ae9fa1ad8af4465bb6ca901f6943fc98eba",
+        "version" : "6.5.16"
+      }
+    },
     {
       "identity" : "leveldb",
       "kind" : "remoteSourceControl",
diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate
index 6dbcabd5844afbb03adf75842a087fbf84e62c43..a4e7006af8b5ad8b450324f2da661967ad272ba0 100644
Binary files a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/TraccarClient/AppDelegate.swift b/TraccarClient/AppDelegate.swift
index 732da69387cb905f29992dd42d94f687961a90db..173dcfee0cd51c8f3ab1fa5b70d015e1816d9dcc 100644
--- a/TraccarClient/AppDelegate.swift
+++ b/TraccarClient/AppDelegate.swift
@@ -17,6 +17,7 @@
 import UIKit
 import CoreData
 import Firebase
+import IQKeyboardManagerSwift
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate {
@@ -67,10 +68,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
             trackingController = TrackingController()
             trackingController?.start()
         }
+        
+        IQKeyboardManager.shared.enable = true
+        IQKeyboardManager.shared.shouldResignOnTouchOutside = true
+        IQKeyboardManager.shared.previousNextDisplayMode = .alwaysShow
+        IQKeyboardManager.shared.toolbarTintColor = .purple
+        
+        setRootNavigation()
 
         return true
     }
     
+    func setRootNavigation() {
+        window = UIWindow(frame: UIScreen.main.bounds)
+        
+        let vc = LoginViewController()
+        vc.window = window
+        
+        window?.rootViewController = vc
+        window?.makeKeyAndVisible()
+    }
+    
     func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
         
         let userDefaults = UserDefaults.standard
diff --git a/TraccarClient/BMTextFieldView/Cell/FieldTableViewCell.swift b/TraccarClient/Custom/BMTextFieldView/Cell/FieldTableViewCell.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Cell/FieldTableViewCell.swift
rename to TraccarClient/Custom/BMTextFieldView/Cell/FieldTableViewCell.swift
diff --git a/TraccarClient/BMTextFieldView/Cell/FieldTableViewCell.xib b/TraccarClient/Custom/BMTextFieldView/Cell/FieldTableViewCell.xib
similarity index 100%
rename from TraccarClient/BMTextFieldView/Cell/FieldTableViewCell.xib
rename to TraccarClient/Custom/BMTextFieldView/Cell/FieldTableViewCell.xib
diff --git a/TraccarClient/BMTextFieldView/KNTextFieldView+Protocols.swift b/TraccarClient/Custom/BMTextFieldView/KNTextFieldView+Protocols.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/KNTextFieldView+Protocols.swift
rename to TraccarClient/Custom/BMTextFieldView/KNTextFieldView+Protocols.swift
diff --git a/TraccarClient/BMTextFieldView/KNTextFieldView.swift b/TraccarClient/Custom/BMTextFieldView/KNTextFieldView.swift
similarity index 99%
rename from TraccarClient/BMTextFieldView/KNTextFieldView.swift
rename to TraccarClient/Custom/BMTextFieldView/KNTextFieldView.swift
index 45e13099f10f44a40e7685b615ab66a392c7486b..3002cef10bc85e5b1fa207a303ec23bb059062b1 100644
--- a/TraccarClient/BMTextFieldView/KNTextFieldView.swift
+++ b/TraccarClient/Custom/BMTextFieldView/KNTextFieldView.swift
@@ -468,7 +468,7 @@ extension KNTextFieldView: UITextFieldDelegate {
             return true
             
         }
-        return false
+        return true
     }
     
     func textFieldDidEndEditing(_ textField: UITextField) {
diff --git a/TraccarClient/BMTextFieldView/KNTextFieldView.xib b/TraccarClient/Custom/BMTextFieldView/KNTextFieldView.xib
similarity index 100%
rename from TraccarClient/BMTextFieldView/KNTextFieldView.xib
rename to TraccarClient/Custom/BMTextFieldView/KNTextFieldView.xib
diff --git a/TraccarClient/BMTextFieldView/KNTextFieldViewHelper.swift b/TraccarClient/Custom/BMTextFieldView/KNTextFieldViewHelper.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/KNTextFieldViewHelper.swift
rename to TraccarClient/Custom/BMTextFieldView/KNTextFieldViewHelper.swift
diff --git a/TraccarClient/BMTextFieldView/Model/KNField.swift b/TraccarClient/Custom/BMTextFieldView/Model/KNField.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Model/KNField.swift
rename to TraccarClient/Custom/BMTextFieldView/Model/KNField.swift
diff --git a/TraccarClient/BMTextFieldView/Model/KNFieldBuilder.swift b/TraccarClient/Custom/BMTextFieldView/Model/KNFieldBuilder.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Model/KNFieldBuilder.swift
rename to TraccarClient/Custom/BMTextFieldView/Model/KNFieldBuilder.swift
diff --git a/TraccarClient/BMTextFieldView/Model/KNFieldDropDownAddressObjectProtocol.swift b/TraccarClient/Custom/BMTextFieldView/Model/KNFieldDropDownAddressObjectProtocol.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Model/KNFieldDropDownAddressObjectProtocol.swift
rename to TraccarClient/Custom/BMTextFieldView/Model/KNFieldDropDownAddressObjectProtocol.swift
diff --git a/TraccarClient/BMTextFieldView/Model/KNFieldDropdownObjectProtocol.swift b/TraccarClient/Custom/BMTextFieldView/Model/KNFieldDropdownObjectProtocol.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Model/KNFieldDropdownObjectProtocol.swift
rename to TraccarClient/Custom/BMTextFieldView/Model/KNFieldDropdownObjectProtocol.swift
diff --git a/TraccarClient/BMTextFieldView/Model/KNFieldType.swift b/TraccarClient/Custom/BMTextFieldView/Model/KNFieldType.swift
similarity index 100%
rename from TraccarClient/BMTextFieldView/Model/KNFieldType.swift
rename to TraccarClient/Custom/BMTextFieldView/Model/KNFieldType.swift
diff --git a/TraccarClient/KNComponentView.swift b/TraccarClient/Custom/KNComponentView.swift
similarity index 100%
rename from TraccarClient/KNComponentView.swift
rename to TraccarClient/Custom/KNComponentView.swift
diff --git a/TraccarClient/KNTableViewCell.swift b/TraccarClient/Custom/KNTableViewCell.swift
similarity index 100%
rename from TraccarClient/KNTableViewCell.swift
rename to TraccarClient/Custom/KNTableViewCell.swift
diff --git a/TraccarClient/JSONField.swift b/TraccarClient/JSONField.swift
index 9e7f1246c91dd0e28a31c4b325836da88d740cb1..0ca1fc2a2ea927afcbccb31ff9e26b296addf858 100644
--- a/TraccarClient/JSONField.swift
+++ b/TraccarClient/JSONField.swift
@@ -80,7 +80,7 @@ enum JSONField: String {
     case option
     case confirm_password
     case code
-    case username = "user_name"
+    case username = "username"
     case business = "business_name"
     case dynamicSpace
     case old_password
@@ -118,7 +118,6 @@ enum JSONField: String {
     case addresses = "address"
     case processing_times = "processing_time"
     case freeShipping = "free_shipping"
-    case authUsername = "username"
     case authBusiness = "business"
     case handling_fees
     
diff --git a/TraccarClient/LoginViewController.swift b/TraccarClient/LoginViewController.swift
deleted file mode 100644
index e87d9066daca558982b97cbe766937a8a8fa60dd..0000000000000000000000000000000000000000
--- a/TraccarClient/LoginViewController.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-//  LoginViewController.swift
-//  TraccarClient
-//
-//  Created by George Makhoul on 25/10/2023.
-//  Copyright © 2023 Traccar. All rights reserved.
-//
-
-import UIKit
-
-final class LoginViewController: UIViewController {
-    
-    override func viewDidLoad() {
-        super.viewDidLoad()
-    }
-    
-}
diff --git a/TraccarClient/LoginViewController/Controller/LoginViewController.swift b/TraccarClient/LoginViewController/Controller/LoginViewController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..00085c326ed36f200cf5a4b5bec9dd524f823feb
--- /dev/null
+++ b/TraccarClient/LoginViewController/Controller/LoginViewController.swift
@@ -0,0 +1,59 @@
+//
+//  LoginViewController.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 25/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import UIKit
+
+final class LoginViewController: UIViewController {
+    // MARK: - Outlets
+    @IBOutlet private weak var tableView: UITableView!
+    
+    // MARK: - Properties
+    private weak var delegate: LoginViewControllerDelegate?
+    
+    private var modelDataSource: LoginDataSource?
+    private var modelController: LoginModelController?
+    var window: UIWindow?
+
+    // MARK: - LifeCycle
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        setupUI()
+    }
+    
+}
+// MARK: - UI
+extension LoginViewController {
+    private func setupUI() {
+        setupTableView()
+    }
+    
+    private func setupTableView() {
+        modelDataSource = LoginDataSource()
+        modelController = LoginModelController(delegate: self, viewController: self)
+        
+        modelDataSource?.outputProtocol = modelController
+        modelController?.inputProtocol = modelDataSource
+        
+        tableView.delegate = modelDataSource
+        tableView.dataSource = modelDataSource
+        
+        tableView.keyboardDismissMode = .interactive
+        tableView.set(cells: [FieldTableViewCell.self])
+        tableView.isScrollEnabled = false
+        tableView.reloadData()
+    }
+    
+}
+
+// MARK: - LoginViewControllerDelegate
+extension LoginViewController: LoginViewControllerDelegate {
+    func updateUI() {
+        tableView.beginUpdates()
+        tableView.endUpdates()
+    }
+}
diff --git a/TraccarClient/LoginViewController/Model/LoginDataProvider.swift b/TraccarClient/LoginViewController/Model/LoginDataProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..b963f64854c4608b0f34196b5701fb81fda29a97
--- /dev/null
+++ b/TraccarClient/LoginViewController/Model/LoginDataProvider.swift
@@ -0,0 +1,38 @@
+//
+//  LoginDataProvider.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 26/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+final class LoginDataProvider {
+    // MARK: - Properties
+    private var fields: [KNField] = []
+    
+    // MARK: - Methods
+     func signinData() -> [KNField] {
+        let email = KNField { field in
+            field.field = .username
+            field.title = "Username"
+            field.isRequired = true
+            field.type = .text
+        }
+        
+        let password = KNField { field in
+            field.field = .password
+            field.title = "Password"
+            field.isRequired = true
+            field.type = .text
+        }
+        
+        fields = [
+            email,
+            password,
+        ]
+        return fields
+    }
+}
diff --git a/TraccarClient/LoginViewController/Model/LoginDataSource.swift b/TraccarClient/LoginViewController/Model/LoginDataSource.swift
new file mode 100644
index 0000000000000000000000000000000000000000..e043b12cc18dc16af8d97b7097682dda3bd5de2f
--- /dev/null
+++ b/TraccarClient/LoginViewController/Model/LoginDataSource.swift
@@ -0,0 +1,65 @@
+//
+//  LoginDataSource.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 26/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import UIKit
+import Foundation
+
+final class LoginDataSource: NSObject {
+    
+    // MARK: - Properties
+    private var fields: [KNField] = []
+    weak var outputProtocol: LoginOutputProtocol?
+    
+    // MARK: - Init
+    override init() {
+        //
+    }
+}
+
+// MARK: - TableView
+extension LoginDataSource: UITableViewDelegate, UITableViewDataSource {
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        fields.count
+    }
+    
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let field = fields[indexPath.row]
+        
+        if field.type == .text {
+            let cell = tableView.dequeue(withCell: FieldTableViewCell.self)
+            cell.delegate = self
+            
+            cell.set(field: field, indexPath: indexPath)
+            return cell
+        }
+        
+        return UITableViewCell()
+    }
+    
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return fields[indexPath.row].height
+    }
+}
+
+
+// MARK: - Input Protocol
+extension LoginDataSource: LoginInputProtocol {
+    func setFields(fields: [KNField]) {
+        self.fields = fields
+        
+        outputProtocol?.reloadUI()
+    }
+}
+
+// MARK: - Field Protocok
+extension LoginDataSource: KNTextFieldViewDelegate {
+    func updateUI(for field: KNField?) {
+        outputProtocol?.reloadUI()
+    }
+}
+
diff --git a/TraccarClient/LoginViewController/Model/LoginModelController.swift b/TraccarClient/LoginViewController/Model/LoginModelController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..91f99e6395476d50715cc865fc2e4bc2028a4607
--- /dev/null
+++ b/TraccarClient/LoginViewController/Model/LoginModelController.swift
@@ -0,0 +1,46 @@
+//
+//  LoginModelController.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 26/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+final class LoginModelController {
+    // MARK: - Properties
+    var fields: [KNField] = []
+    var viewController: UIViewController
+    private weak var delegate: LoginViewControllerDelegate?
+    weak var window: UIWindow?
+    
+    weak var inputProtocol: LoginInputProtocol? {
+        didSet {
+            setupData()
+        }
+    }
+    
+    // MARK: - Init
+    init(delegate: LoginViewControllerDelegate?, viewController: UIViewController) {
+        self.delegate = delegate
+        self.viewController = viewController
+    }
+    
+    private func setupData() {
+        let dataProvider = LoginDataProvider()
+        fields = dataProvider.signinData()
+        
+        inputProtocol?.setFields(fields: fields)
+    }
+}
+
+// MARK: - Output Protocol
+extension LoginModelController: LoginOutputProtocol {
+    
+    func reloadUI() {
+        delegate?.updateUI()
+    }
+}
+
diff --git a/TraccarClient/LoginViewController/Model/LoginViewControllerProtocol.swift b/TraccarClient/LoginViewController/Model/LoginViewControllerProtocol.swift
new file mode 100644
index 0000000000000000000000000000000000000000..d88270b1a235436092c2e53abc5dbc9b3accd1a5
--- /dev/null
+++ b/TraccarClient/LoginViewController/Model/LoginViewControllerProtocol.swift
@@ -0,0 +1,23 @@
+//
+//  LoginViewControllerProtocol.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 26/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import UIKit
+import Foundation
+
+protocol LoginViewControllerDelegate: AnyObject {
+    func updateUI()
+
+}
+
+protocol LoginInputProtocol: AnyObject {
+    func setFields(fields: [KNField])
+}
+
+protocol LoginOutputProtocol: AnyObject {
+    func reloadUI()
+}
diff --git a/TraccarClient/LoginViewController.xib b/TraccarClient/LoginViewController/View/LoginViewController.xib
similarity index 80%
rename from TraccarClient/LoginViewController.xib
rename to TraccarClient/LoginViewController/View/LoginViewController.xib
index 00485dc670700e704dfd8239a7a826be7a12cc3c..df509156c5949ee86121c7eed68324f7089da194 100644
--- a/TraccarClient/LoginViewController.xib
+++ b/TraccarClient/LoginViewController/View/LoginViewController.xib
@@ -19,6 +19,7 @@
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LoginViewController" customModule="TraccarClient" customModuleProvider="target">
             <connections>
+                <outlet property="tableView" destination="cqa-qG-jss" id="WXO-8H-fjI"/>
                 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
             </connections>
         </placeholder>
@@ -46,14 +47,22 @@
                     <nil key="textColor"/>
                     <nil key="highlightedColor"/>
                 </label>
+                <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="cqa-qG-jss">
+                    <rect key="frame" x="32" y="313.66666666666674" width="329" height="472.33333333333326"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                </tableView>
             </subviews>
             <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
             <color key="backgroundColor" systemColor="systemBackgroundColor"/>
             <constraints>
+                <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="cqa-qG-jss" secondAttribute="trailing" constant="32" id="3jQ-sI-aAm"/>
                 <constraint firstItem="rPb-N8-5pB" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="CJs-Qh-u3u"/>
+                <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="cqa-qG-jss" secondAttribute="bottom" constant="32" id="Dqf-I3-asf"/>
                 <constraint firstItem="rPb-N8-5pB" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="75" id="HjK-k3-B52"/>
+                <constraint firstItem="cqa-qG-jss" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="32" id="bDg-CD-ZNz"/>
                 <constraint firstItem="ejG-GP-Evp" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="nuW-Lh-yVC"/>
                 <constraint firstItem="ejG-GP-Evp" firstAttribute="top" secondItem="jC6-Ly-QKC" secondAttribute="bottom" constant="7" id="o0G-Yj-sgP"/>
+                <constraint firstItem="cqa-qG-jss" firstAttribute="top" secondItem="ejG-GP-Evp" secondAttribute="bottom" constant="25" id="uqb-3w-Sf4"/>
                 <constraint firstItem="jC6-Ly-QKC" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="x2w-Bh-kGc"/>
                 <constraint firstItem="jC6-Ly-QKC" firstAttribute="top" secondItem="rPb-N8-5pB" secondAttribute="bottom" constant="10" id="yvR-wY-vOb"/>
             </constraints>
diff --git a/TraccarClient/TraccarClient-Info.plist b/TraccarClient/TraccarClient-Info.plist
index b07535fbfe47b6286e64d311cc5511ae6ea555aa..dad50640b1bb1c0a127d5b7883883ef43be07559 100644
--- a/TraccarClient/TraccarClient-Info.plist
+++ b/TraccarClient/TraccarClient-Info.plist
@@ -35,6 +35,27 @@
 	<string>This is a tracking application and therefore requires access to location services</string>
 	<key>NSLocationWhenInUseUsageDescription</key>
 	<string>This is a tracking application and therefore requires access to location services</string>
+	<key>UIAppFonts</key>
+	<array>
+		<string>Montserrat-Black.ttf</string>
+		<string>Montserrat-BlackItalic.ttf</string>
+		<string>Montserrat-Bold.ttf</string>
+		<string>Montserrat-BoldItalic.ttf</string>
+		<string>Montserrat-ExtraBold.ttf</string>
+		<string>Montserrat-ExtraBoldItalic.ttf</string>
+		<string>Montserrat-ExtraLight.ttf</string>
+		<string>Montserrat-ExtraLightItalic.ttf</string>
+		<string>Montserrat-Italic.ttf</string>
+		<string>Montserrat-Light.ttf</string>
+		<string>Montserrat-LightItalic.ttf</string>
+		<string>Montserrat-Medium.ttf</string>
+		<string>Montserrat-MediumItalic.ttf</string>
+		<string>Montserrat-Regular.ttf</string>
+		<string>Montserrat-SemiBold.ttf</string>
+		<string>Montserrat-SemiBoldItalic.ttf</string>
+		<string>Montserrat-Thin.ttf</string>
+		<string>Montserrat-ThinItalic.ttf</string>
+	</array>
 	<key>UIApplicationShortcutItems</key>
 	<array>
 		<dict>
@@ -85,28 +106,9 @@
 		<string>UIInterfaceOrientationLandscapeLeft</string>
 		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
+	<key>UIUserInterfaceStyle</key>
+	<string>Light</string>
 	<key>UIViewControllerBasedStatusBarAppearance</key>
 	<false/>
-	<key>UIAppFonts</key>
-	<array>
-		<string>Montserrat-Black.ttf</string>
-		<string>Montserrat-BlackItalic.ttf</string>
-		<string>Montserrat-Bold.ttf</string>
-		<string>Montserrat-BoldItalic.ttf</string>
-		<string>Montserrat-ExtraBold.ttf</string>
-		<string>Montserrat-ExtraBoldItalic.ttf</string>
-		<string>Montserrat-ExtraLight.ttf</string>
-		<string>Montserrat-ExtraLightItalic.ttf</string>
-		<string>Montserrat-Italic.ttf</string>
-		<string>Montserrat-Light.ttf</string>
-		<string>Montserrat-LightItalic.ttf</string>
-		<string>Montserrat-Medium.ttf</string>
-		<string>Montserrat-MediumItalic.ttf</string>
-		<string>Montserrat-Regular.ttf</string>
-		<string>Montserrat-SemiBold.ttf</string>
-		<string>Montserrat-SemiBoldItalic.ttf</string>
-		<string>Montserrat-Thin.ttf</string>
-		<string>Montserrat-ThinItalic.ttf</string>
-	</array>
 </dict>
 </plist>
diff --git a/TraccarClient/UITableView.swift b/TraccarClient/UITableView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..b3ccd8a9454fabbdc17a138aa07bcecfa3cb003e
--- /dev/null
+++ b/TraccarClient/UITableView.swift
@@ -0,0 +1,99 @@
+//
+//  UITableView.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 26/10/2023.
+//  Copyright © 2023 Traccar. All rights reserved.
+//
+
+import UIKit
+
+extension UITableView {
+    
+    var automatic: CGFloat {
+        UITableView.automaticDimension
+    }
+    
+    // MARK: - Set Cell & Setup Table
+    func set(cell: UITableViewCell.Type) {
+        tableFooterView = UIView()
+        tableHeaderView = UIView()
+        separatorStyle = .none
+        backgroundColor = .clear
+        
+        register(cell: cell)
+    }
+    
+    func set(cells: [UITableViewCell.Type]) {
+        tableFooterView = UIView()
+        tableHeaderView = UIView()
+        separatorStyle = .none
+        backgroundColor = .clear
+        
+        register(cells: cells)
+    }
+    
+    // MARK: - Register Cell
+    func register(cell: UITableViewCell.Type) {
+        let nib = UINib(nibName: cell.name, bundle: nil)
+        register(nib, forCellReuseIdentifier: cell.name)
+    }
+       
+    func register(cells: [UITableViewCell.Type]) {
+        cells.forEach {
+            let nib = UINib(nibName: $0.name, bundle: nil)
+            register(nib, forCellReuseIdentifier: $0.name)
+        }
+    }
+    
+    func register(header: UITableViewHeaderFooterView.Type) {
+        let nib = UINib(nibName: header.name, bundle: nil)
+        register(nib, forHeaderFooterViewReuseIdentifier: header.name)
+    }
+    
+    func register(headers: [UITableViewHeaderFooterView.Type]) {
+        headers.forEach {
+            let nib = UINib(nibName: $0.name, bundle: nil)
+            register(nib, forHeaderFooterViewReuseIdentifier: $0.name)
+        }
+    }
+    
+    // MARK: - Dequeue Cell
+    func dequeue<CellType: UITableViewCell>(withCell cell: CellType.Type, at indexPath: IndexPath) -> CellType {
+        dequeueReusableCell(withIdentifier: cell.name, for: indexPath) as! CellType
+    }
+    
+    func dequeue<CellType: UITableViewCell>(withCell cell: CellType.Type) -> CellType {
+        dequeueReusableCell(withIdentifier: cell.name) as! CellType
+    }
+    
+    func dequeue<HeaderType: UITableViewHeaderFooterView>(withHeader header: HeaderType.Type, at section: Int) -> HeaderType {
+        dequeueReusableHeaderFooterView(withIdentifier: header.name) as! HeaderType
+    }
+    
+    // table's content view
+    var contentHeight: CGFloat {
+        var height: CGFloat = 0
+        
+        for section in 0..<numberOfSections {
+            height += rectForHeader(inSection: section).height
+            
+            let rows = numberOfRows(inSection: section)
+            for row in 0..<rows {
+                height += rectForRow(at: IndexPath(row: row, section: section)).height
+            }
+        }
+        
+        return height
+    }
+    
+    func prefetchSpinner() {
+        let spinner = UIActivityIndicatorView(style: .medium)
+        spinner.color = .purple
+        spinner.startAnimating()
+        spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: bounds.width, height: CGFloat(44))
+        tableFooterView = spinner
+        tableFooterView?.isHidden = false
+    }
+}
+