import SwiftUI struct LoginView: View { @EnvironmentObject var viewModel: PDSViewModel @State private var serverURL = "" @State private var password = "" @State private var isLoggingIn = false @State private var showingDebugInfo = false @State private var debugLogs: [String] = [] var body: some View { VStack(spacing: 20) { Image(systemName: "server.rack") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 100, height: 100) .foregroundColor(.blue) Text("PDS Manager") .font(.largeTitle) .fontWeight(.bold) VStack(alignment: .leading, spacing: 20) { TextField("Server URL", text: $serverURL) .textFieldStyle(RoundedBorderTextFieldStyle()) .autocapitalization(.none) .disableAutocorrection(true) .keyboardType(.URL) SecureField("Admin Password", text: $password) .textFieldStyle(RoundedBorderTextFieldStyle()) } .padding(.horizontal, 40) Button { login() } label: { if isLoggingIn { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) .frame(maxWidth: .infinity) .padding() } else { Text("Login") .frame(maxWidth: .infinity) .padding() } } .background(Color.blue) .foregroundColor(.white) .cornerRadius(10) .padding(.horizontal, 40) .disabled(serverURL.isEmpty || password.isEmpty || isLoggingIn) if let errorMessage = viewModel.errorMessage { Text(errorMessage) .foregroundColor(.red) .font(.callout) .multilineTextAlignment(.center) .padding(.horizontal, 40) .padding(.vertical, 10) .background(Color.red.opacity(0.1)) .cornerRadius(8) } Divider() .padding(.vertical, 10) .padding(.horizontal, 40) Button { enterDemoMode() } label: { HStack { Image(systemName: "rectangle.fill.on.rectangle.fill.circle") .imageScale(.medium) Text("Enter Demo Mode") } .frame(maxWidth: .infinity) .padding() } .background(Color.green) .foregroundColor(.white) .cornerRadius(10) .padding(.horizontal, 40) Button("Show Debug Info") { showingDebugInfo.toggle() } .font(.caption) .foregroundColor(.secondary) .padding(.top, 10) if showingDebugInfo { ScrollView { VStack(alignment: .leading, spacing: 8) { ForEach(debugLogs, id: \.self) { log in Text(log) .font(.system(.caption, design: .monospaced)) } } .frame(maxWidth: .infinity, alignment: .leading) .padding() } .frame(height: 200) .background(Color.black.opacity(0.05)) .cornerRadius(8) .padding(.horizontal, 40) } Spacer() } .padding(.top, 50) .onAppear { // Add some example connection info debugLogs.append("Example URLs:") debugLogs.append("https://bsky.social - Main Bluesky server") debugLogs.append("https://bsky.atri.dad - Your local server") debugLogs.append("http://localhost:3000 - Local development PDS") } } private func enterDemoMode() { debugLogs.append("Entering demo mode...") viewModel.enableDemoMode() } private func login() { isLoggingIn = true // Add debug info debugLogs.append("Attempting login to: \(serverURL)") // Sanitize the URL to ensure it has the correct format var cleanURL = serverURL.trimmingCharacters(in: .whitespacesAndNewlines) if !cleanURL.hasPrefix("http://") && !cleanURL.hasPrefix("https://") { cleanURL = "http://\(cleanURL)" debugLogs.append("Added http:// prefix: \(cleanURL)") } // Remove trailing slash if present if cleanURL.hasSuffix("/") { cleanURL.removeLast() debugLogs.append("Removed trailing slash: \(cleanURL)") } debugLogs.append("Using final URL: \(cleanURL)") Task { await viewModel.login(serverURL: cleanURL, username: "admin", password: password) isLoggingIn = false if let error = viewModel.errorMessage { debugLogs.append("Login failed: \(error)") } else { debugLogs.append("Login successful!") } } } }