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("PayfritLogoLight") .resizable() .scaledToFit() .frame(width: 200) ProgressView() .tint(.payfritGreen) } } } private func checkAuthWithBiometrics() async { let creds = await AuthStorage.shared.loadAuth() guard creds != nil else { return } let context = LAContext() context.localizedCancelTitle = "Use Password" var error: NSError? let canUseBiometrics = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) #if targetEnvironment(simulator) // Skip biometrics on simulator — test on real device await appState.loadSavedAuth() return #endif guard canUseBiometrics else { await appState.loadSavedAuth() return } do { let success = try await context.evaluatePolicy( .deviceOwnerAuthenticationWithBiometrics, localizedReason: "Sign in to Payfrit Works" ) if success { await appState.loadSavedAuth() } } catch { // User tapped "Use Password" or biometrics failed — show login screen NSLog("PAYFRIT [biometrics] cancelled/failed: \(error.localizedDescription)") } } }