import SwiftUI struct ScanScreen: View { @EnvironmentObject var appState: AppState @StateObject private var scanner = BarcodeScanner() @State private var showManualEntry = false @State private var isLoading = false @State private var showProduct = false var body: some View { NavigationStack { ZStack { Color.black.ignoresSafeArea() if scanner.isScanning { CameraPreviewView(scanner: scanner) .ignoresSafeArea() // Scan overlay VStack { Spacer() // Scan region indicator RoundedRectangle(cornerRadius: 20) .strokeBorder(Color.green, lineWidth: 3) .frame(width: 280, height: 180) .overlay { Text("Position barcode here") .font(.caption) .foregroundColor(.white.opacity(0.7)) } Spacer() // Manual entry button Button { showManualEntry = true } label: { HStack { Image(systemName: "keyboard") Text("Enter Manually") } .font(.headline) .foregroundColor(.white) .padding() .background(Color.white.opacity(0.2)) .cornerRadius(12) } .padding(.bottom, 40) } } else if isLoading { VStack(spacing: 20) { ProgressView() .scaleEffect(1.5) .tint(.white) Text("Looking up product...") .foregroundColor(.white) } } else { // Start scan prompt VStack(spacing: 30) { Image(systemName: "barcode.viewfinder") .font(.system(size: 80)) .foregroundColor(.green) Text("Scan a Barcode") .font(.title) .foregroundColor(.white) Text("Point your camera at a food product barcode to see its health rating and find healthier alternatives.") .font(.body) .foregroundColor(.gray) .multilineTextAlignment(.center) .padding(.horizontal, 40) Button { Task { let hasPermission = await scanner.checkPermission() if hasPermission { scanner.startScanning() } } } label: { Text("Start Scanning") .font(.headline) .foregroundColor(.black) .frame(maxWidth: .infinity) .padding() .background(Color.green) .cornerRadius(12) } .padding(.horizontal, 40) Button { showManualEntry = true } label: { Text("Enter Barcode Manually") .font(.subheadline) .foregroundColor(.green) } } } } .navigationTitle("Scan") .navigationBarTitleDisplayMode(.inline) .toolbarColorScheme(.dark, for: .navigationBar) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { if scanner.isScanning { Button("Cancel") { scanner.stopScanning() } .foregroundColor(.white) } } } .sheet(isPresented: $showManualEntry) { ManualEntrySheet { barcode in lookupProduct(barcode: barcode) } } .navigationDestination(isPresented: $showProduct) { if let product = appState.currentProduct { ProductScreen(product: product) .environmentObject(appState) } } .onChange(of: scanner.scannedCode) { newCode in if let code = newCode { lookupProduct(barcode: code) } } } } private func lookupProduct(barcode: String) { isLoading = true scanner.stopScanning() Task { do { let product = try await APIService.shared.lookupProduct(barcode: barcode) await MainActor.run { appState.setCurrentProduct(product) isLoading = false showProduct = true // Add to history if authenticated if appState.isAuthenticated { Task { try? await APIService.shared.addToHistory(productId: product.id) } } } } catch { await MainActor.run { isLoading = false appState.showError(error.localizedDescription) scanner.reset() } } } } }