diff --git a/password/view/detail/DetailView.swift b/password/view/detail/DetailView.swift index 28caf8e..0c7bb93 100644 --- a/password/view/detail/DetailView.swift +++ b/password/view/detail/DetailView.swift @@ -63,6 +63,15 @@ struct DetailView: View { elapsedTime = -1 } } + HStack { + Spacer() + Text("Attempts: \(viewModel.statistics.totalCount)") + Spacer() + Text("Successful: \(viewModel.statistics.successCount) (\(viewModel.statistics.successRate, specifier: "%.2f")%)") + Spacer() + Text("Avg. time: \(viewModel.statistics.averageTime, specifier: "%.2f")s") + Spacer() + } } .padding() } diff --git a/password/view/detail/DetailViewModel.swift b/password/view/detail/DetailViewModel.swift index a6f4ad3..e8f8574 100644 --- a/password/view/detail/DetailViewModel.swift +++ b/password/view/detail/DetailViewModel.swift @@ -8,6 +8,13 @@ import Foundation import SwiftData +struct PasswordAttemptStatistics { + let totalCount: Int + let successCount: Int + let successRate: Double + let averageTime: Double +} + class DetailViewModel: ObservableObject { let passwordID: UUID @@ -18,6 +25,29 @@ class DetailViewModel: ObservableObject { @Published var password: Password @Published var passwordKC: PasswordKC @Published var passwordAttempts: [PasswordAttempt] + + var statistics: PasswordAttemptStatistics { + guard !passwordAttempts.isEmpty else { + return PasswordAttemptStatistics( + totalCount: 0, + successCount: 0, + successRate: 0.00, + averageTime: 0.00 + ) + } + + let totalCount = passwordAttempts.count + let successCount = passwordAttempts.filter { $0.isSuccessful }.count + let successRate = Double(successCount) / Double(totalCount) * 100 + let averageTime = passwordAttempts.count > 0 ? passwordAttempts.reduce(0) { $0 + $1.typingTime } / Double(passwordAttempts.count) : 0 + + return PasswordAttemptStatistics( + totalCount: totalCount, + successCount: successCount, + successRate: successRate, + averageTime: averageTime + ) + } @MainActor init(context: ModelContext, passwordID id: UUID) {