// // SignupView.swift // medmap // import SwiftUI struct SignupView: View { @StateObject private var viewModel = SignupViewModel() @FocusState private var focusedField: Field? private enum Field { case email case password case confirmationPassword } var body: some View { ZStack { Color.appBackground.ignoresSafeArea() VStack(spacing: 0) { HStack { Image("splashLogo") .resizable() .scaledToFit() .frame(width: 120, height: 76) .accessibilityHidden(true) Spacer() } .padding(.top, 32) .padding(.horizontal, 32) Spacer() VStack(alignment: .leading, spacing: 24) { Text("Criar nova conta") .font(.jakartaBold24) .foregroundStyle(.white) VStack(spacing: 14) { field( placeholder: "Email", icon: "envelope", text: $viewModel.email, focusedField: .email, contentType: .emailAddress, keyboardType: .emailAddress ) field( placeholder: "Palavra-passe (min. 8 caracteres)", icon: "lock", text: $viewModel.password, focusedField: .password, contentType: .newPassword, isSecure: true ) field( placeholder: "Confirmar palavra-passe", icon: "lock", text: $viewModel.confirmationPassword, focusedField: .confirmationPassword, contentType: .newPassword, isSecure: true, submitLabel: .go ) { Task { await viewModel.signup() } } } if let errorMessage = viewModel.errorMessage { Text(errorMessage) .font(.jakartaRegular14) .foregroundStyle(Color.loginErrorText) .frame(maxWidth: .infinity) .multilineTextAlignment(.center) } Button { focusedField = nil Task { await viewModel.signup() } } label: { Group { if viewModel.isLoading { ProgressView().tint(Color.loginButtonText) } else { Text("Registar").font(.jakartaBold16) } } .frame(maxWidth: .infinity) .frame(height: 46) } .foregroundStyle(Color.loginButtonText) .background(Color.loginButtonBackground) .clipShape(RoundedRectangle(cornerRadius: 8)) .disabled(!viewModel.canSubmit) .opacity(viewModel.canSubmit ? 1 : 0.55) } .padding(.horizontal, 32) Spacer() VStack(spacing: 8) { Button("Ja tem conta? Entrar") { viewModel.showLogin() } .font(.jakartaRegular14) .foregroundStyle(.white.opacity(0.88)) Text("MedMap") .font(.jakartaRegular12) .foregroundStyle(.white.opacity(0.6)) } .padding(.bottom, 24) } } .navigationBarHidden(true) } private func field( placeholder: String, icon: String, text: Binding, focusedField: Field, contentType: UITextContentType, keyboardType: UIKeyboardType = .default, isSecure: Bool = false, submitLabel: SubmitLabel = .next, onSubmit: @escaping () -> Void = {} ) -> some View { HStack(spacing: 10) { Image(systemName: icon) .foregroundStyle(.white) .frame(width: 18) ZStack(alignment: .leading) { if text.wrappedValue.isEmpty { Text(placeholder).foregroundStyle(Color.loginPlaceholder) } if isSecure { SecureField("", text: text) } else { TextField("", text: text) .keyboardType(keyboardType) .textInputAutocapitalization(.never) .autocorrectionDisabled() } } .foregroundStyle(.white) .tint(.white) .font(.jakartaRegular16) .textContentType(contentType) .focused($focusedField, equals: focusedField) .submitLabel(submitLabel) .onSubmit(onSubmit) } .padding(.horizontal, 14) .frame(height: 46) .background(Color.loginFieldBackground) .overlay { RoundedRectangle(cornerRadius: 8) .stroke(Color.loginFieldBorder, lineWidth: 1) } .clipShape(RoundedRectangle(cornerRadius: 8)) .accessibilityLabel(placeholder) } } #Preview { SignupView() }