import SwiftUI /// "Registrieren" screen. On success this does NOT sign the user in — the /// backend requires the emailed confirmation link to be opened first, exactly /// like the web signup flow (see `AppState.signup(name:email:password:)`) — /// so success routes to `VerificationPendingView` via `onSignupSucceeded`, /// not into `AppState`. struct SignupView: View { @EnvironmentObject private var appState: AppState var onSignupSucceeded: (_ email: String) -> Void var onSwitchToLogin: () -> Void @State private var name = "" @State private var email = "" @State private var password = "" @State private var isSubmitting = false private var canSubmit: Bool { !email.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && !password.isEmpty && !isSubmitting } var body: some View { ScrollView { VStack(spacing: ZenithSpacing.md) { Text("Konto erstellen") .zenithHeadlineLgStyle() .padding(.top, ZenithSpacing.lg) VStack(spacing: ZenithSpacing.sm) { ZenithTextField( label: "Name (optional)", text: $name, textContentType: .name, autocapitalization: .words ) ZenithTextField( label: "E-Mail", text: $email, keyboardType: .emailAddress, textContentType: .username, autocapitalization: .never, autocorrectionDisabled: true ) ZenithTextField( label: "Passwort", text: $password, isSecure: true, textContentType: .newPassword ) } if let error = appState.lastError { Text(error) .zenithBodySmStyle(color: .zenithError) .multilineTextAlignment(.center) } Button { Task { await submit() } } label: { Group { if isSubmitting { ProgressView() .tint(.white) } else { Text("Konto erstellen") } } .frame(maxWidth: .infinity) } .buttonStyle(.zenithPrimary) .disabled(!canSubmit) Button("Schon ein Konto? Anmelden") { appState.lastError = nil onSwitchToLogin() } .buttonStyle(.zenithPlain) .padding(.top, ZenithSpacing.xs) } .padding(.horizontal, ZenithSpacing.md) .padding(.bottom, ZenithSpacing.lg) } .scrollDismissesKeyboard(.interactively) .background(Color.zenithBg) } private func submit() async { guard canSubmit else { return } isSubmitting = true defer { isSubmitting = false } let trimmedEmail = email.trimmingCharacters(in: .whitespacesAndNewlines) let trimmedName = name.trimmingCharacters(in: .whitespacesAndNewlines) let succeeded = await appState.signup( name: trimmedName.isEmpty ? nil : trimmedName, email: trimmedEmail, password: password ) if succeeded { onSignupSucceeded(trimmedEmail) } } }