import SwiftUI struct LoginView: View { @StateObject private var vm = LoginViewModel() @State private var navigateToDashboard = false var body: some View { NavigationStack { ZStack { Color.white.ignoresSafeArea() VStack(spacing: 0) { Spacer() // Logo + device VStack(spacing: 16) { Image("nas_logo_clean") .resizable() .scaledToFit() .frame(width: 100, height: 100) .clipShape(RoundedRectangle(cornerRadius: 22)) Text("Forge") .font(.system(size: 22, weight: .bold)) .foregroundColor(AppTheme.textPrimary) } Spacer().frame(height: 40) // Account avatar + name HStack(spacing: 12) { ZStack { Circle() .fill(AppTheme.blue) .frame(width: 48, height: 48) Text("AB") .font(.system(size: 16, weight: .bold)) .foregroundColor(.white) } VStack(alignment: .leading, spacing: 2) { Text("Albert") .font(.system(size: 17, weight: .semibold)) .foregroundColor(AppTheme.textPrimary) Text("NAS Account") .font(AppTheme.captionFont) .foregroundColor(AppTheme.textSecondary) } } .padding(.bottom, 32) // Face ID button Button(action: { vm.authenticateWithFaceID() }) { HStack(spacing: 10) { Image(systemName: "faceid") .font(.system(size: 20, weight: .medium)) Text("Sign in with Face ID") .font(.system(size: 17, weight: .semibold)) } .foregroundColor(.white) .frame(maxWidth: .infinity) .frame(height: 52) .background(AppTheme.blue) .clipShape(RoundedRectangle(cornerRadius: 14)) } .padding(.horizontal, 32) .disabled(vm.isAuthenticating) if let error = vm.authError { Text(error) .font(AppTheme.captionFont) .foregroundColor(AppTheme.red) .padding(.top, 12) } Spacer() // More link Button("More") { vm.showMoreSheet = true } .font(.system(size: 15, weight: .regular)) .foregroundColor(AppTheme.textSecondary) .padding(.bottom, 40) } } .navigationDestination(isPresented: $navigateToDashboard) { MainTabView() } .sheet(isPresented: $vm.showMoreSheet) { MoreOptionsSheet(isPresented: $vm.showMoreSheet, onAuthenticated: { vm.showMoreSheet = false navigateToDashboard = true }) .presentationDetents([.height(220)]) } } .onAppear { vm.onAuthenticated = { navigateToDashboard = true } } } } struct MoreOptionsSheet: View { @Binding var isPresented: Bool var onAuthenticated: (() -> Void)? @State private var showPasswordEntry = false var body: some View { VStack(spacing: 0) { Capsule() .fill(Color(hex: "#D1D5DB")) .frame(width: 40, height: 4) .padding(.top, 12) .padding(.bottom, 20) Button("Password") { showPasswordEntry = true } .font(.system(size: 17, weight: .semibold)) .foregroundColor(AppTheme.textPrimary) .frame(maxWidth: .infinity) .padding(.vertical, 14) Divider() Button("Another account") { isPresented = false onAuthenticated?() } .font(.system(size: 17, weight: .regular)) .foregroundColor(AppTheme.textPrimary) .frame(maxWidth: .infinity) .padding(.vertical, 14) Divider() Button("Cancel") { isPresented = false } .font(.system(size: 17, weight: .regular)) .foregroundColor(AppTheme.textSecondary) .frame(maxWidth: .infinity) .padding(.vertical, 14) } .background(Color.white) } }