import Foundation @MainActor final class AuthViewModel: ObservableObject { @Published var email = "" @Published var password = "" @Published var loading = false @Published var error: String? func login(onSuccess: @escaping () -> Void) async { guard !loading else { return } loading = true error = nil defer { loading = false } do { let result = try await APIClient.shared.login( email: email.trimmingCharacters(in: .whitespaces), password: password ) SessionStore.shared.saveSession( token: result.token, name: result.user.name, email: result.user.email, avatarURL: result.user.avatarUrl ) await PushTokenRegistrar.registerIfLoggedIn() onSuccess() } catch { self.error = (error as? LocalizedError)?.errorDescription ?? error.localizedDescription } } } @MainActor final class RegisterViewModel: ObservableObject { @Published var name = "" @Published var email = "" @Published var password = "" @Published var passwordConfirmation = "" @Published var company = "" @Published var address = "" @Published var city = "" @Published var country = Countries.default @Published var state = "" @Published var zipcode = "" @Published var phone = "" @Published var terms = false @Published var saving = false @Published var error: String? var canSubmit: Bool { !name.isEmpty && !email.isEmpty && password.count >= 8 && passwordConfirmation == password && !address.isEmpty && !city.isEmpty && !state.isEmpty && !zipcode.isEmpty && !phone.isEmpty && terms } func register(onSuccess: @escaping () -> Void) async { guard !saving else { return } if password != passwordConfirmation { error = "Passwords do not match." return } if !terms { error = "Please accept the terms to continue." return } saving = true error = nil defer { saving = false } do { let result = try await APIClient.shared.register(RegisterRequest( name: name.trimmingCharacters(in: .whitespaces), email: email.trimmingCharacters(in: .whitespaces), password: password, passwordConfirmation: passwordConfirmation, company: company.trimmingCharacters(in: .whitespaces).isEmpty ? nil : company.trimmingCharacters(in: .whitespaces), address: address.trimmingCharacters(in: .whitespaces), city: city.trimmingCharacters(in: .whitespaces), state: state, country: country.code, zipcode: zipcode.trimmingCharacters(in: .whitespaces), phoneCc: country.dialCode, phone: phone.trimmingCharacters(in: .whitespaces), mobileCc: nil, mobile: nil, terms: true )) SessionStore.shared.saveSession( token: result.token, name: result.user.name, email: result.user.email, avatarURL: result.user.avatarUrl ) await PushTokenRegistrar.registerIfLoggedIn() onSuccess() } catch { self.error = (error as? LocalizedError)?.errorDescription ?? error.localizedDescription } } }