Add Ladill Mini native Android and iOS apps.
Deploy Ladill Mini / deploy (push) Successful in 35s

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>
This commit is contained in:
isaacclad
2026-06-11 22:30:35 +00:00
co-authored by Cursor
parent ec9f09f997
commit ea6afb80a4
172 changed files with 12114 additions and 0 deletions
@@ -0,0 +1,78 @@
import Foundation
@MainActor
final class HomeViewModel: ObservableObject {
@Published var overviewState: LoadState<Overview> = .idle
@Published var qrsState: LoadState<[PaymentQr]> = .idle
@Published var paymentsState: LoadState<[Payment]> = .idle
@Published var payoutsState: LoadState<Payouts> = .idle
@Published var hasPayout: Bool?
@Published var unreadCount = 0
@Published var overviewRefreshing = false
func loadUnreadCount() async {
if let count = try? await APIClient.shared.unreadNotificationCount() {
unreadCount = count
}
}
func loadOverview() async {
overviewState = .loading
do {
let data = try await APIClient.shared.overview()
overviewState = .success(data)
} catch {
overviewState = .failure((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
}
}
func refreshOverview() async {
guard !overviewRefreshing else { return }
overviewRefreshing = true
defer { overviewRefreshing = false }
await loadOverview()
await loadPayoutStatus()
}
func loadQrs() async {
qrsState = .loading
do {
qrsState = .success(try await APIClient.shared.paymentQrs())
} catch {
qrsState = .failure((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
}
}
func loadPayments() async {
paymentsState = .loading
do {
paymentsState = .success(try await APIClient.shared.payments())
} catch {
paymentsState = .failure((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
}
}
func loadPayouts() async {
payoutsState = .loading
do {
payoutsState = .success(try await APIClient.shared.payouts())
} catch {
payoutsState = .failure((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
}
}
func loadPayoutStatus() async {
do {
hasPayout = try await APIClient.shared.payoutAccount() != nil
} catch {
// Leave hasPayout unchanged when the check fails.
}
}
func logout(onComplete: @escaping () -> Void) async {
await PushTokenRegistrar.unregister()
await APIClient.shared.logout()
SessionStore.shared.clear()
onComplete()
}
}