209 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
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
 | 
						||
}
 |