156 lines
4.4 KiB
Swift
156 lines
4.4 KiB
Swift
import Foundation
|
|
import ComposeApp
|
|
import Combine
|
|
|
|
@MainActor
|
|
class LoginViewModel: ObservableObject {
|
|
// MARK: - Published Properties
|
|
@Published var username: String = ""
|
|
@Published var password: String = ""
|
|
@Published var isLoading: Bool = false
|
|
@Published var errorMessage: String?
|
|
@Published var isAuthenticated: Bool = false
|
|
@Published var isVerified: Bool = false
|
|
@Published var currentUser: User?
|
|
|
|
// MARK: - Private Properties
|
|
private let authApi: AuthApi
|
|
private let tokenStorage: TokenStorage
|
|
|
|
// MARK: - Initialization
|
|
init() {
|
|
self.authApi = AuthApi(client: ApiClient_iosKt.createHttpClient())
|
|
self.tokenStorage = TokenStorage()
|
|
|
|
// Initialize TokenStorage with platform-specific manager
|
|
self.tokenStorage.initialize(manager: TokenManager.init())
|
|
|
|
// Check if user is already logged in
|
|
checkAuthenticationStatus()
|
|
}
|
|
|
|
// MARK: - Public Methods
|
|
func login() {
|
|
guard !username.isEmpty else {
|
|
errorMessage = "Username is required"
|
|
return
|
|
}
|
|
|
|
guard !password.isEmpty else {
|
|
errorMessage = "Password is required"
|
|
return
|
|
}
|
|
|
|
isLoading = true
|
|
errorMessage = nil
|
|
|
|
let loginRequest = LoginRequest(username: username, password: password)
|
|
|
|
do {
|
|
// Call the KMM AuthApi login method
|
|
authApi.login(request: loginRequest) { result, error in
|
|
if let successResult = result as? ApiResultSuccess<AuthResponse> {
|
|
self.handleSuccess(results: successResult)
|
|
return
|
|
}
|
|
|
|
if let error = error {
|
|
self.handleError(error: error)
|
|
return
|
|
}
|
|
|
|
self.isLoading = false
|
|
self.isAuthenticated = false
|
|
print("uknown error")
|
|
}
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
func handleError(error: any Error) {
|
|
self.isLoading = false
|
|
self.isAuthenticated = false
|
|
print(error)
|
|
}
|
|
|
|
@MainActor
|
|
func handleSuccess(results: ApiResultSuccess<AuthResponse>) {
|
|
if let token = results.data?.token,
|
|
let user = results.data?.user {
|
|
self.tokenStorage.saveToken(token: token)
|
|
|
|
// Store user data and verification status
|
|
self.currentUser = user
|
|
self.isVerified = user.verified
|
|
self.isLoading = false
|
|
|
|
print("Login successful! Token: token")
|
|
print("User: \(user.username), Verified: \(user.verified)")
|
|
print("isVerified set to: \(self.isVerified)")
|
|
|
|
// Initialize lookups repository after successful login
|
|
LookupsManager.shared.initialize()
|
|
|
|
// Update authentication state AFTER setting verified status
|
|
// Small delay to ensure state updates are processed
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
self.isAuthenticated = true
|
|
print("isAuthenticated set to true, isVerified is: \(self.isVerified)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func logout() {
|
|
let token = tokenStorage.getToken()
|
|
|
|
if let token = token {
|
|
// Call logout API
|
|
authApi.logout(token: token) { _, _ in
|
|
// Ignore result, clear token anyway
|
|
}
|
|
}
|
|
|
|
// Clear token from storage
|
|
tokenStorage.clearToken()
|
|
|
|
// Clear lookups data on logout
|
|
LookupsManager.shared.clear()
|
|
|
|
// Reset state
|
|
isAuthenticated = false
|
|
isVerified = false
|
|
currentUser = nil
|
|
username = ""
|
|
password = ""
|
|
errorMessage = nil
|
|
|
|
print("Logged out - all state reset")
|
|
}
|
|
|
|
func clearError() {
|
|
errorMessage = nil
|
|
}
|
|
|
|
// MARK: - Private Methods
|
|
private func checkAuthenticationStatus() {
|
|
isAuthenticated = tokenStorage.hasToken()
|
|
|
|
// If already authenticated, initialize lookups
|
|
if isAuthenticated {
|
|
LookupsManager.shared.initialize()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Error Types
|
|
enum LoginError: LocalizedError {
|
|
case unknownError
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .unknownError:
|
|
return "An unknown error occurred"
|
|
}
|
|
}
|
|
}
|