import SwiftUI struct LoginScreen: View { @EnvironmentObject var appState: AppState @State private var username = "" @State private var password = "" @State private var showPassword = false @State private var isLoading = false @State private var error: String? var body: some View { GeometryReader { geo in ScrollView { VStack(spacing: 12) { Image("PayfritLogoLight") .resizable() .scaledToFit() .frame(width: 220) .padding(.horizontal, 16) Text("Payfrit Works") .font(.system(size: 28, weight: .bold)) Text("Sign in to view and claim tasks") .foregroundColor(.secondary) if IS_DEV { Text("DEV MODE — password: 123456") .font(.caption) .foregroundColor(.red) .fontWeight(.medium) } VStack(spacing: 12) { TextField("Email or Phone", text: $username) .textFieldStyle(.roundedBorder) .textContentType(.emailAddress) .autocapitalization(.none) .disableAutocorrection(true) // Password field with visibility toggle ZStack(alignment: .trailing) { Group { if showPassword { TextField("Password", text: $password) .textContentType(.password) } else { SecureField("Password", text: $password) .textContentType(.password) } } .textFieldStyle(.roundedBorder) .onSubmit { login() } Button { showPassword.toggle() } label: { Image(systemName: showPassword ? "eye.slash.fill" : "eye.fill") .foregroundColor(.secondary) .font(.subheadline) } .padding(.trailing, 8) } } .padding(.top, 8) if let error = error { HStack { Image(systemName: "exclamationmark.circle.fill") .foregroundColor(.red) Text(error) .foregroundColor(.red) .font(.callout) Spacer() } .padding(12) .background(Color.red.opacity(0.1)) .cornerRadius(8) } Button(action: login) { if isLoading { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) .frame(maxWidth: .infinity, minHeight: 44) } else { Text("Sign In") .font(.headline) .frame(maxWidth: .infinity, minHeight: 44) } } .buttonStyle(.borderedProminent) .tint(.payfritGreen) .disabled(isLoading) } .padding(.horizontal, 24) .frame(minHeight: geo.size.height) } } .background(Color(.systemGroupedBackground)) } private func login() { let user = username.trimmingCharacters(in: .whitespaces) let pass = password guard !user.isEmpty, !pass.isEmpty else { error = "Please enter username and password" return } isLoading = true error = nil Task { do { let response = try await APIService.shared.login(username: user, password: pass) let resolvedPhoto = APIService.resolvePhotoUrl(response.photoUrl) await AuthStorage.shared.saveAuth( userId: response.userId, token: response.token, userName: response.userFirstName, photoUrl: resolvedPhoto ) appState.setAuth( userId: response.userId, token: response.token, userName: response.userFirstName, photoUrl: resolvedPhoto ) } catch { self.error = error.localizedDescription isLoading = false } } } }