
- 创建SettingPage视图,包含用户信息管理、头像设置、昵称编辑等功能。 - 实现SettingViewModel,处理设置页面的业务逻辑,包括头像上传、昵称更新等。 - 添加相机和相册选择功能,支持头像更换。 - 更新MainPage和MainViewModel,添加导航逻辑以支持设置页面的访问。 - 完善本地化支持,确保多语言兼容性。 - 新增相关测试建议,确保功能完整性和用户体验。
126 lines
4.4 KiB
Swift
126 lines
4.4 KiB
Swift
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: {}
|
||
// )
|
||
//}
|