import SwiftUI struct LoginView: View { @Bindable var viewModel: AuthViewModel var appState: AppState var body: some View { NavigationStack { ScrollView { VStack(spacing: 20) { Image(systemName: "lock.shield.fill") .font(.system(size: 60)) .foregroundStyle(.blue) .padding(.top, 40) Text("Encrypted Chat") .font(.largeTitle.bold()) Text("End-to-end encrypted messaging") .font(.subheadline) .foregroundStyle(.secondary) VStack(spacing: 16) { // Server config DisclosureGroup("Server") { TextField("Host", text: $viewModel.serverHost) .textContentType(.URL) .autocapitalization(.none) TextField("Port", text: $viewModel.serverPort) .keyboardType(.numberPad) Toggle("Use TLS", isOn: $viewModel.useTLS) } .padding(.horizontal) TextField("Email", text: $viewModel.email) .textContentType(.emailAddress) .keyboardType(.emailAddress) .autocapitalization(.none) .textFieldStyle(.roundedBorder) SecureField("Password", text: $viewModel.password) .textContentType(.password) .textFieldStyle(.roundedBorder) if viewModel.mode == .register { TextField("Username", text: $viewModel.username) .textContentType(.username) .autocapitalization(.none) .textFieldStyle(.roundedBorder) SecureField("Confirm Password", text: $viewModel.confirmPassword) .textFieldStyle(.roundedBorder) } if let error = viewModel.errorMessage { Text(error) .foregroundStyle(.red) .font(.caption) .multilineTextAlignment(.center) } Button(action: { Task { if viewModel.mode == .login { await viewModel.login(appState: appState) } else { await viewModel.register(appState: appState) } } }) { if viewModel.isLoading { ProgressView() .frame(maxWidth: .infinity) } else { Text(viewModel.mode == .login ? "Login" : "Register") .frame(maxWidth: .infinity) } } .buttonStyle(.borderedProminent) .disabled(viewModel.isLoading) Button(viewModel.mode == .login ? "Don't have an account? Register" : "Already have an account? Login") { viewModel.mode = viewModel.mode == .login ? .register : .login viewModel.errorMessage = nil } .font(.caption) } .padding(.horizontal, 32) } } .sheet(isPresented: $viewModel.showConfirmation) { ConfirmationSheet(viewModel: viewModel, appState: appState) } } } } struct ConfirmationSheet: View { @Bindable var viewModel: AuthViewModel var appState: AppState var body: some View { VStack(spacing: 20) { Text("Confirm Registration") .font(.title2.bold()) if let msg = viewModel.registrationMessage { Text(msg) .font(.subheadline) .foregroundStyle(.secondary) .multilineTextAlignment(.center) } TextField("Confirmation Code", text: $viewModel.confirmationCode) .textFieldStyle(.roundedBorder) .keyboardType(.numberPad) if let error = viewModel.errorMessage { Text(error) .foregroundStyle(.red) .font(.caption) } Button("Confirm") { Task { await viewModel.confirmRegistration(appState: appState) } } .buttonStyle(.borderedProminent) .disabled(viewModel.isLoading) } .padding(32) } }