feat: 更新EMailLoginView和IDLoginView以增强用户体验和界面一致性

- 将LocalizedString替换为硬编码字符串,提升代码可读性。
- 重构输入框组件,使用CustomInputField以统一输入框样式和逻辑。
- 更新按钮文本和样式,确保一致性和视觉效果。
- 调整布局和间距,优化用户界面体验。
- 增加验证码输入框的获取按钮功能,提升交互性。
This commit is contained in:
edwinQQQ
2025-07-31 19:14:14 +08:00
parent dc8ba46f86
commit fdfa39f0b7
2 changed files with 261 additions and 232 deletions

View File

@@ -25,7 +25,7 @@ struct EMailLoginView: View {
if codeCountdown > 0 {
return "\(codeCountdown)s"
} else {
return LocalizedString("email_login.get_code", comment: "")
return "Get"
}
}
@@ -151,117 +151,125 @@ private struct LoginContentView: View {
.padding(.horizontal, 16)
.padding(.top, 8)
Spacer().frame(height: 60)
Text(LocalizedString("email_login.title", comment: ""))
.font(.system(size: 28, weight: .medium))
Text("Email Login")
.font(.system(size: 28, weight: .bold))
.foregroundColor(.white)
.padding(.bottom, 80)
.padding(.bottom, 60)
VStack(spacing: 20) {
VStack(spacing: 24) {
//
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("email icon")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20)
Text(LocalizedString("email_login.email", comment: ""))
.font(.system(size: 16))
.foregroundColor(.white)
}
TextField("", text: $email)
.textFieldStyle(PlainTextFieldStyle())
.font(.system(size: 16))
.foregroundColor(.white)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(Color.white.opacity(0.1))
.cornerRadius(8)
.focused($focusedField, equals: .email)
.keyboardType(.emailAddress)
.autocapitalization(.none)
}
emailInputField
//
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("id icon")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20)
Text(LocalizedString("email_login.verification_code", comment: ""))
.font(.system(size: 16))
.foregroundColor(.white)
}
HStack {
TextField("", text: $verificationCode)
.textFieldStyle(PlainTextFieldStyle())
.font(.system(size: 16))
.foregroundColor(.white)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(Color.white.opacity(0.1))
.cornerRadius(8)
.focused($focusedField, equals: .verificationCode)
.keyboardType(.numberPad)
Button(action: {
store.send(.getVerificationCodeTapped)
}) {
Text(getCodeButtonText)
.font(.system(size: 14, weight: .medium))
.foregroundColor(.white)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(isCodeButtonEnabled ? Color.blue : Color.gray)
.cornerRadius(8)
}
.disabled(!isCodeButtonEnabled)
}
}
//
Button(action: {
store.send(.loginButtonTapped(email: email, verificationCode: verificationCode))
}) {
if store.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.scaleEffect(1.2)
} else {
Text(LocalizedString("email_login.login", comment: ""))
.font(.system(size: 16, weight: .medium))
.foregroundColor(.white)
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 16)
.background(isLoginButtonEnabled ? Color.blue : Color.gray)
.cornerRadius(8)
.disabled(!isLoginButtonEnabled)
.padding(.top, 20)
//
if let errorMessage = store.errorMessage {
Text(errorMessage)
.font(.system(size: 14))
.foregroundColor(.red)
.padding(.top, 16)
.padding(.horizontal, 32)
}
Spacer()
//
verificationCodeInputField
}
.padding(.horizontal, 32)
// API Loading
APILoadingEffectView()
Spacer()
.frame(height: 80)
//
Button(action: {
store.send(.loginButtonTapped(email: email, verificationCode: verificationCode))
}) {
if store.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.scaleEffect(1.2)
} else {
Text("Login")
.font(.system(size: 16, weight: .medium))
.foregroundColor(.white)
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 16)
.background(isLoginButtonEnabled ? Color(red: 0.5, green: 0.3, blue: 0.8) : Color.gray)
.cornerRadius(8)
.disabled(!isLoginButtonEnabled)
.padding(.horizontal, 32)
Spacer()
}
}
}
}
.navigationBarHidden(true)
}
// MARK: - UI Components
private var emailInputField: some View {
ZStack {
RoundedRectangle(cornerRadius: 25)
.fill(Color.white.opacity(0.1))
.overlay(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.white.opacity(0.3), lineWidth: 1)
)
.frame(height: 56)
TextField("", text: $email)
.placeholder(when: email.isEmpty) {
Text("Please enter email")
.foregroundColor(.white.opacity(0.6))
}
.foregroundColor(.white)
.font(.system(size: 16))
.padding(.horizontal, 24)
.keyboardType(.emailAddress)
.autocapitalization(.none)
.focused($focusedField, equals: .email)
}
}
private var verificationCodeInputField: some View {
ZStack {
RoundedRectangle(cornerRadius: 25)
.fill(Color.white.opacity(0.1))
.overlay(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.white.opacity(0.3), lineWidth: 1)
)
.frame(height: 56)
HStack {
TextField("", text: $verificationCode)
.placeholder(when: verificationCode.isEmpty) {
Text("Please enter verification code")
.foregroundColor(.white.opacity(0.6))
}
.foregroundColor(.white)
.font(.system(size: 16))
.keyboardType(.numberPad)
.focused($focusedField, equals: .verificationCode)
//
Button(action: {
store.send(.getVerificationCodeTapped)
}) {
ZStack {
if store.isCodeLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.scaleEffect(0.7)
} else {
Text(getCodeButtonText)
.font(.system(size: 14, weight: .medium))
.foregroundColor(.white)
}
}
.frame(width: 60, height: 36)
.background(
RoundedRectangle(cornerRadius: 15)
.fill(Color.white.opacity(isCodeButtonEnabled ? 0.2 : 0.1))
)
}
.disabled(!isCodeButtonEnabled || store.isCodeLoading)
}
.padding(.horizontal, 24)
}
}
}
//#Preview {