import SwiftUI struct ConnectView: View { @StateObject private var vm = ConnectViewModel() @State private var navigateToDashboard = false var body: some View { NavigationStack { ZStack { Color.white.ignoresSafeArea() ScrollView { VStack(spacing: 0) { // Logo Image("nas_logo_clean") .resizable() .scaledToFit() .frame(width: 56, height: 56) .clipShape(RoundedRectangle(cornerRadius: 12)) .padding(.top, 48) .padding(.bottom, 28) // Protocol picker Picker("Protocol", selection: $vm.selectedProtocol) { ForEach(NASProtocol.allCases, id: \.self) { Text($0.rawValue).tag($0) } } .pickerStyle(.segmented) .padding(.horizontal, 20) .padding(.bottom, 20) // Form card VStack(spacing: 0) { fieldRow(icon: "network", placeholder: "IP Address or hostname", text: $vm.host, keyboardType: .URL) Divider().padding(.leading, 52) fieldRow(icon: "person", placeholder: "Username", text: $vm.username, keyboardType: .emailAddress) Divider().padding(.leading, 52) secureFieldRow(icon: "lock", placeholder: "Password", text: $vm.password) Divider().padding(.leading, 52) // Folder picker row Button(action: { if vm.isConnected { vm.showFolderBrowser = true } }) { HStack(spacing: 12) { Image(systemName: "folder") .font(.system(size: 16)) .foregroundColor(vm.isConnected ? AppTheme.blue : AppTheme.textTertiary) .frame(width: 28) Text(vm.remotePath == "/" ? "Destination folder" : vm.remotePath) .font(AppTheme.bodyFont) .foregroundColor(vm.remotePath == "/" ? AppTheme.textTertiary : AppTheme.textPrimary) Spacer() Image(systemName: "chevron.right") .font(.system(size: 13)) .foregroundColor(AppTheme.textTertiary) } .padding(.horizontal, 16) .padding(.vertical, 14) } } .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius)) .overlay( RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius) .stroke(vm.isConnected ? AppTheme.connectedBorder : (vm.verifyError != nil ? AppTheme.red : AppTheme.cardBorder), lineWidth: vm.isConnected ? 1.5 : 1) ) .padding(.horizontal, 20) if let error = vm.verifyError { Text(error) .font(AppTheme.captionFont) .foregroundColor(AppTheme.red) .padding(.top, 10) .padding(.horizontal, 24) } if vm.isConnected { Text("Connected successfully") .font(AppTheme.captionFont) .foregroundColor(AppTheme.green) .padding(.top, 10) } // Connect button — sits BELOW the card with explicit gap Spacer().frame(height: 24) Button(action: { if vm.isConnected { navigateToDashboard = true } else { Task { await vm.verify() } } }) { Group { if vm.isVerifying { ProgressView().tint(.white) } else { Text(vm.isConnected ? "Connected — continue" : "Connect") .font(.system(size: 17, weight: .semibold)) } } .foregroundColor(.white) .frame(maxWidth: .infinity) .frame(height: 52) .background(vm.isConnected ? AppTheme.green : AppTheme.blue) .clipShape(RoundedRectangle(cornerRadius: 14)) } .disabled(!vm.canConnect) .padding(.horizontal, 20) .padding(.bottom, 40) } } } .navigationTitle("Connect to NAS") .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $navigateToDashboard) { MainTabView() } .sheet(isPresented: $vm.showFolderBrowser) { if let conn = ConnectionStore.shared.savedConnection { BrowseView(connection: conn, selectedPath: $vm.remotePath) } } } } private func fieldRow(icon: String, placeholder: String, text: Binding, keyboardType: UIKeyboardType = .default) -> some View { HStack(spacing: 12) { Image(systemName: icon) .font(.system(size: 16)) .foregroundColor(AppTheme.textSecondary) .frame(width: 28) TextField(placeholder, text: text) .font(AppTheme.bodyFont) .keyboardType(keyboardType) .autocorrectionDisabled() .textInputAutocapitalization(.never) } .padding(.horizontal, 16) .padding(.vertical, 14) } private func secureFieldRow(icon: String, placeholder: String, text: Binding) -> some View { HStack(spacing: 12) { Image(systemName: icon) .font(.system(size: 16)) .foregroundColor(AppTheme.textSecondary) .frame(width: 28) SecureField(placeholder, text: text) .font(AppTheme.bodyFont) } .padding(.horizontal, 16) .padding(.vertical, 14) } }