import SwiftUI // MARK: - IDLogin View struct IDLoginPage: View { @StateObject private var viewModel = IDLoginViewModel() let onBack: () -> Void let onLoginSuccess: () -> Void var body: some View { GeometryReader { geometry in ZStack { // 背景 LoginBackgroundView() VStack(spacing: 0) { // 顶部导航栏 LoginHeaderView(onBack: { viewModel.onBackTapped() }) Spacer() .frame(height: 60) // 标题 Text("ID Login") .font(.system(size: 28, weight: .bold)) .foregroundColor(.white) .padding(.bottom, 60) // 输入框区域 VStack(spacing: 24) { // 用户ID输入框(只允许数字) CustomInputField( type: .number, placeholder: "Please enter ID", text: $viewModel.userID ) // 密码输入框(带眼睛按钮) CustomInputField( type: .password, placeholder: "Please enter password", text: $viewModel.password, isPasswordVisible: $viewModel.isPasswordVisible ) } .padding(.horizontal, 32) Spacer() .frame(height: 80) // 忘记密码按钮 HStack { Spacer() Button(action: { viewModel.onRecoverPasswordTapped() }) { Text("Forgot Password?") .font(.system(size: 14)) .foregroundColor(.white.opacity(0.8)) } } .padding(.horizontal, 32) .padding(.bottom, 20) // 登录按钮 LoginButtonView( isLoading: viewModel.isLoading || viewModel.isTicketLoading, isEnabled: viewModel.isLoginButtonEnabled, onTap: { viewModel.onLoginTapped() } ) .padding(.horizontal, 32) // Ticket加载状态提示 if viewModel.isTicketLoading { Text("正在获取会话票据...") .font(.system(size: 14)) .foregroundColor(.white.opacity(0.8)) .padding(.top, 8) } // 错误信息显示 if let errorMessage = viewModel.errorMessage { Text(errorMessage) .font(.system(size: 14)) .foregroundColor(.red) .padding(.top, 8) .padding(.horizontal, 32) } Spacer() } } } .navigationBarHidden(true) .navigationDestination(isPresented: $viewModel.showRecoverPassword) { RecoverPasswordPage( onBack: { viewModel.onRecoverPasswordBack() } ) .navigationBarHidden(true) } .onAppear { viewModel.onBack = onBack viewModel.onLoginSuccess = onLoginSuccess } .onChange(of: viewModel.loginStep) { _, newStep in debugInfoSync("🔄 IDLoginView: loginStep 变化为 \(newStep)") if newStep == .completed { debugInfoSync("✅ IDLoginView: 登录成功,准备关闭自身") } } } } //#Preview { // IDLoginPage( // onBack: {}, // onLoginSuccess: {} // ) //}