// // LoginView.swift // WekoutThotViewer // // Created by Trey Tartt on 6/18/24. // import SwiftUI struct LoginView: View { @State var email: String = "" @State var password: String = "" @Environment(\.dismiss) var dismiss let completion: (() -> Void) @State var isLoggingIn: Bool = false @State var errorTitle = "" @State var errorMessage = "" @State var hasError: Bool = false var body: some View { VStack { TextField("Email", text: $email) .textContentType(.username) .textInputAutocapitalization(.never) .autocorrectionDisabled(true) .keyboardType(.emailAddress) .padding() .background(WerkoutTheme.surfaceCard.opacity(0.8)) .clipShape(RoundedRectangle(cornerRadius: WerkoutTheme.buttonRadius, style: .continuous)) .overlay( RoundedRectangle(cornerRadius: WerkoutTheme.buttonRadius, style: .continuous) .strokeBorder(WerkoutTheme.textSecondary.opacity(0.4), lineWidth: 1) ) .foregroundStyle(WerkoutTheme.textPrimary) .padding(.horizontal) .padding(.top, 25) .accessibilityLabel("Email") .submitLabel(.next) SecureField("Password", text: $password) .textContentType(.password) .padding() .background(WerkoutTheme.surfaceCard.opacity(0.8)) .clipShape(RoundedRectangle(cornerRadius: WerkoutTheme.buttonRadius, style: .continuous)) .overlay( RoundedRectangle(cornerRadius: WerkoutTheme.buttonRadius, style: .continuous) .strokeBorder(WerkoutTheme.textSecondary.opacity(0.4), lineWidth: 1) ) .foregroundStyle(WerkoutTheme.textPrimary) .padding(.horizontal) .textInputAutocapitalization(.never) .autocorrectionDisabled(true) .accessibilityLabel("Password") .submitLabel(.go) if isLoggingIn { ProgressView("Logging In") .padding() .foregroundStyle(WerkoutTheme.textPrimary) .progressViewStyle(CircularProgressViewStyle(tint: WerkoutTheme.accent)) .scaleEffect(1.5, anchor: .center) } else { Button("Login", action: { login() }) .font(.system(size: 16, weight: .bold)) .foregroundStyle(WerkoutTheme.textPrimary) .frame(maxWidth: .infinity, alignment: .center) .frame(height: 44) .glassEffect(.regular.interactive()) .tint(WerkoutTheme.accent) .clipShape(RoundedRectangle(cornerRadius: WerkoutTheme.buttonRadius, style: .continuous)) .padding() .frame(maxWidth: .infinity) .disabled(password.isEmpty || email.isEmpty) .accessibilityLabel("Log in") .accessibilityHint("Logs in using the entered email and password") } Spacer() } .padding() .background( ZStack { Image("icon") .resizable() .edgesIgnoringSafeArea(.all) .scaledToFill() .accessibilityHidden(true) LinearGradient( colors: [ Color.black.opacity(0.0), Color.black.opacity(0.6) ], startPoint: .top, endPoint: .bottom ) .edgesIgnoringSafeArea(.all) } ) .alert(errorTitle, isPresented: $hasError, actions: { }, message: { Text(errorMessage) }) } func login() { let postData = [ "email": email, "password": password ] isLoggingIn = true UserStore.shared.login(postData: postData, completion: { success in isLoggingIn = false if success { completion() dismiss() } else { errorTitle = "error logging in" errorMessage = "invalid credentials" hasError = true } }) } } struct LoginView_Previews: PreviewProvider { static var previews: some View { LoginView(completion: { }) } }