payfrit-beacon-ios/PayfritBeacon/Views/RootView.swift
2026-02-01 23:39:29 -08:00

88 lines
2.8 KiB
Swift

import SwiftUI
import LocalAuthentication
struct RootView: View {
@EnvironmentObject var appState: AppState
@State private var isCheckingAuth = true
@State private var isDev = false
var body: some View {
Group {
if isCheckingAuth {
loadingView
} else if appState.isAuthenticated {
BusinessSelectionScreen()
} else {
LoginScreen()
}
}
.animation(.easeInOut(duration: 0.3), value: appState.isAuthenticated)
.overlay(alignment: .bottomLeading) {
if isDev {
Text("DEV")
.font(.caption.bold())
.foregroundColor(.white)
.frame(width: 80, height: 20)
.background(Color.orange)
.rotationEffect(.degrees(45))
.offset(x: -20, y: -6)
.allowsHitTesting(false)
}
}
.task {
isDev = await APIService.shared.isDev
await checkAuthWithBiometrics()
isCheckingAuth = false
}
}
private var loadingView: some View {
ZStack {
Color.white.ignoresSafeArea()
VStack(spacing: 16) {
Image(systemName: "sensor.tag.radiowaves.forward.fill")
.font(.system(size: 60))
.foregroundColor(.payfritGreen)
Text("Payfrit Beacon")
.font(.title2.bold())
ProgressView()
.tint(.payfritGreen)
}
}
}
private func checkAuthWithBiometrics() async {
let creds = await AuthStorage.shared.loadAuth()
guard creds != nil else { return }
#if targetEnvironment(simulator)
await appState.loadSavedAuth()
return
#else
let context = LAContext()
context.localizedCancelTitle = "Use Password"
var error: NSError?
let canUseBiometrics = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
guard canUseBiometrics else {
// No biometrics available allow login with saved credentials
await appState.loadSavedAuth()
return
}
do {
let success = try await context.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Sign in to Payfrit Beacon"
)
if success {
await appState.loadSavedAuth()
}
} catch {
// User cancelled biometrics still allow them in with saved credentials
NSLog("PAYFRIT [biometrics] cancelled/failed: \(error.localizedDescription)")
await appState.loadSavedAuth()
}
#endif
}
}