Files
ladill-mini/apps/ios/LadillMini/Features/Auth/AuthViewModel.swift
T
isaaccladandCursor ea6afb80a4
Deploy Ladill Mini / deploy (push) Successful in 35s
Add Ladill Mini native Android and iOS apps.
Ship full-featured mobile clients with auth, payments, QRs, push notifications, and iOS polish including Figtree typography, app icons, and QR previews.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 22:30:35 +00:00

104 lines
3.5 KiB
Swift

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
}
}
}