import SwiftUI /// Modal Sheet allowing logged-in users to change their password. struct ChangePasswordModalView: View { @Environment(\.dismiss) private var dismiss @ObservedObject var authManager: AuthManager = .shared @State private var oldPasswordInput: String = "" @State private var newPasswordInput: String = "" @State private var confirmPasswordInput: String = "" @State private var errorMessage: String? @State private var successToast: String? var body: some View { ZStack { Color.spaceBlack.ignoresSafeArea() VStack(spacing: 20) { // Header HStack { Text("修改密码") .font(.system(size: 18, weight: .bold)) .foregroundStyle(Color.primary) Spacer() Button { dismiss() } label: { Image(systemName: "xmark.circle.fill") .font(.system(size: 22)) .foregroundStyle(Color.secondary.opacity(0.6)) } } .padding(.horizontal, 20) .padding(.top, 20) VStack(spacing: 14) { passwordField(label: "当前原密码", text: $oldPasswordInput, placeholder: "请输入当前账号原密码") passwordField(label: "新密码", text: $newPasswordInput, placeholder: "请输入新密码 (不少于 6 位)") passwordField(label: "确认新密码", text: $confirmPasswordInput, placeholder: "请再次输入新密码") if let error = errorMessage { Text(error) .font(.system(size: 12)) .foregroundStyle(Color.recordingRed) .frame(maxWidth: .infinity, alignment: .leading) } if let toast = successToast { Text(toast) .font(.system(size: 12)) .foregroundStyle(Color.green) .frame(maxWidth: .infinity, alignment: .leading) } } .padding(.horizontal, 20) .padding(.top, 10) Spacer() Button { handleChangePassword() } label: { if authManager.isProcessing { ProgressView() .tint(Color.spaceBlack) } else { Text("确认修改密码") .font(.system(size: 15, weight: .semibold)) .foregroundStyle(Color.spaceBlack) } } .frame(maxWidth: .infinity) .padding(.vertical, 14) .background(Color.primary) .cornerRadius(8) .padding(.horizontal, 20) .padding(.bottom, 24) .disabled(authManager.isProcessing) } } } private func passwordField(label: String, text: Binding, placeholder: String) -> some View { VStack(alignment: .leading, spacing: 6) { Text(label) .font(.system(size: 12)) .foregroundStyle(Color.secondary) HStack(spacing: 12) { Image(systemName: "lock") .font(.system(size: 14)) .foregroundStyle(Color.secondary) .frame(width: 20) SecureField(placeholder, text: text) .font(.system(size: 14)) } .padding(.horizontal, 14) .padding(.vertical, 12) .background(Color.cardBackground.opacity(0.3)) .businessBorder(cornerRadius: 8) } } private func handleChangePassword() { errorMessage = nil successToast = nil guard !oldPasswordInput.isEmpty else { errorMessage = "请输入原密码" return } guard newPasswordInput.count >= 6 else { errorMessage = "新密码长度不能少于 6 位" return } guard newPasswordInput == confirmPasswordInput else { errorMessage = "两次输入的无缝新密码不一致" return } authManager.changePassword(oldPassword: oldPasswordInput, newPassword: newPasswordInput) { success, err in if success { successToast = "密码修改成功!请记牢新密码" DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { dismiss() } } else { errorMessage = err ?? "原密码错误或修改失败" } } } }