ios_app_v2/yobble/Views/Tab/Settings/ChangePasswordView.swift
2025-10-07 01:51:15 +03:00

209 lines
8.9 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
struct ChangePasswordView: View {
@StateObject private var viewModel = ChangePasswordViewModel()
@State private var oldPassword = ""
@State private var newPassword = ""
@State private var confirmPassword = ""
@State private var isOldPasswordVisible = false
@State private var isNewPasswordVisible = false
@State private var isConfirmPasswordVisible = false
@State private var alertData: AlertData?
private var isOldPasswordValid: Bool {
oldPassword.count >= 8 && oldPassword.count <= 128
}
private var isOldPasswordSame: Bool {
oldPassword == newPassword
}
private var isNewPasswordValid: Bool {
newPassword.count >= 8 && newPassword.count <= 128
}
private var isPasswordConfirmValid: Bool {
newPassword == confirmPassword
}
private var isButtonEnabled: Bool {
isPasswordConfirmValid && !isOldPasswordSame && isNewPasswordValid && isOldPasswordValid && !viewModel.isLoading
}
var body: some View {
Form {
Section {
HStack {
if isOldPasswordVisible {
TextField(NSLocalizedString("Старый пароль", comment: "Старый пароль"), text: $oldPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.password)
.frame(maxWidth: .infinity, alignment: .leading)
} else {
SecureField(NSLocalizedString("Старый пароль", comment: "Старый пароль"), text: $oldPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.password)
.frame(maxWidth: .infinity, alignment: .leading)
}
Button(action: {
isOldPasswordVisible.toggle()
}) {
Image(systemName: isOldPasswordVisible ? "eye.slash" : "eye")
.foregroundColor(.gray)
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 4)
if !oldPassword.isEmpty {
Image(systemName: isOldPasswordValid ? "checkmark.circle" : "xmark.circle")
.foregroundColor(isOldPasswordValid ? .green : .red)
}
}
HStack {
if isNewPasswordVisible {
TextField(NSLocalizedString("Новый пароль", comment: "Новый пароль"), text: $newPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.newPassword)
.frame(maxWidth: .infinity, alignment: .leading)
} else {
SecureField(NSLocalizedString("Новый пароль", comment: "Новый пароль"), text: $newPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.newPassword)
.frame(maxWidth: .infinity, alignment: .leading)
}
Button(action: {
isNewPasswordVisible.toggle()
}) {
Image(systemName: isNewPasswordVisible ? "eye.slash" : "eye")
.foregroundColor(.gray)
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 4)
if !newPassword.isEmpty {
let isAllValid = isNewPasswordValid && !isOldPasswordSame
Image(systemName: isAllValid ? "checkmark.circle" : "xmark.circle")
.foregroundColor(isAllValid ? .green : .red)
}
}
if isOldPasswordSame && !newPassword.isEmpty {
Text(NSLocalizedString("Ты шо ебанутый? А ниче тот факт что новый пароль должен отличаться от старого.", comment: ""))
.font(.caption)
.foregroundColor(.red)
}
HStack {
if isConfirmPasswordVisible {
TextField(NSLocalizedString("Подтверждение пароля", comment: "Подтверждение пароля"), text: $confirmPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.password)
.frame(maxWidth: .infinity, alignment: .leading)
} else {
SecureField(NSLocalizedString("Подтверждение пароля", comment: "Подтверждение пароля"), text: $confirmPassword)
.autocapitalization(.none)
.disableAutocorrection(true)
.textContentType(.password)
.frame(maxWidth: .infinity, alignment: .leading)
}
Button(action: {
isConfirmPasswordVisible.toggle()
}) {
Image(systemName: isConfirmPasswordVisible ? "eye.slash" : "eye")
.foregroundColor(.gray)
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 4)
if !confirmPassword.isEmpty {
Image(systemName: isPasswordConfirmValid ? "checkmark.circle" : "xmark.circle")
.foregroundColor(isPasswordConfirmValid ? .green : .red)
}
}
if !confirmPassword.isEmpty && !isPasswordConfirmValid {
Text(NSLocalizedString("Пароли не совпадают.", comment: ""))
.font(.caption)
.foregroundColor(.red)
}
}
Button(action: {
viewModel.changePassword(oldPassword: oldPassword, newPassword: newPassword)
}) {
if viewModel.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
.padding()
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.6))
.cornerRadius(8)
} else {
Text(NSLocalizedString("Применить", comment: ""))
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(isButtonEnabled ? Color.blue : Color.gray)
.cornerRadius(8)
}
}
.disabled(!isButtonEnabled)
.buttonStyle(PlainButtonStyle())
.listRowInsets(EdgeInsets())
.listRowBackground(Color.clear)
}
.navigationTitle(NSLocalizedString("Изменение пароля", comment: ""))
.onChange(of: viewModel.successMessage) { message in
guard let message else { return }
alertData = AlertData(kind: .success, message: message)
}
.onChange(of: viewModel.errorMessage) { message in
guard let message else { return }
alertData = AlertData(kind: .error, message: message)
}
.alert(item: $alertData) { data in
Alert(
title: Text(data.kind == .success
? NSLocalizedString("Пароль обновлен", comment: "")
: NSLocalizedString("Ошибка", comment: "")),
message: Text(data.message),
dismissButton: .default(Text(NSLocalizedString("OK", comment: ""))) {
switch data.kind {
case .success:
oldPassword = ""
newPassword = ""
confirmPassword = ""
viewModel.successMessage = nil
case .error:
viewModel.errorMessage = nil
}
alertData = nil
}
)
}
}
}
private struct AlertData: Identifiable {
enum Kind {
case success
case error
}
let id = UUID()
let kind: Kind
let message: String
}