99 lines
2.8 KiB
Swift
99 lines
2.8 KiB
Swift
import Foundation
|
|
|
|
struct MonthlyCheckInEntry: Codable, Equatable {
|
|
var note: String?
|
|
var rating: Int?
|
|
var mood: MonthlyCheckInMood?
|
|
var completionTime: Double?
|
|
var createdAt: Double
|
|
|
|
var completionDate: Date? {
|
|
completionTime.map { Date(timeIntervalSince1970: $0) }
|
|
}
|
|
}
|
|
|
|
enum MonthlyCheckInMood: String, Codable, CaseIterable, Identifiable {
|
|
case energized
|
|
case confident
|
|
case balanced
|
|
case cautious
|
|
case stressed
|
|
|
|
var id: String { rawValue }
|
|
|
|
var title: String {
|
|
switch self {
|
|
case .energized: return String(localized: "mood_energized_title")
|
|
case .confident: return String(localized: "mood_confident_title")
|
|
case .balanced: return String(localized: "mood_balanced_title")
|
|
case .cautious: return String(localized: "mood_cautious_title")
|
|
case .stressed: return String(localized: "mood_stressed_title")
|
|
}
|
|
}
|
|
|
|
var iconName: String {
|
|
switch self {
|
|
case .energized: return "flame.fill"
|
|
case .confident: return "hand.thumbsup.fill"
|
|
case .balanced: return "leaf.fill"
|
|
case .cautious: return "exclamationmark.triangle.fill"
|
|
case .stressed: return "exclamationmark.octagon.fill"
|
|
}
|
|
}
|
|
|
|
var detail: String {
|
|
switch self {
|
|
case .energized: return String(localized: "mood_energized_detail")
|
|
case .confident: return String(localized: "mood_confident_detail")
|
|
case .balanced: return String(localized: "mood_balanced_detail")
|
|
case .cautious: return String(localized: "mood_cautious_detail")
|
|
case .stressed: return String(localized: "mood_stressed_detail")
|
|
}
|
|
}
|
|
}
|
|
|
|
struct MonthlyCheckInAchievement: Identifiable, Equatable {
|
|
let key: String
|
|
let title: String
|
|
let detail: String
|
|
let icon: String
|
|
|
|
var id: String { key }
|
|
}
|
|
|
|
struct MonthlyCheckInAchievementStatus: Identifiable, Equatable {
|
|
let achievement: MonthlyCheckInAchievement
|
|
let isUnlocked: Bool
|
|
|
|
var id: String { achievement.key }
|
|
}
|
|
|
|
struct MonthlyCheckInStats: Equatable {
|
|
let currentStreak: Int
|
|
let bestStreak: Int
|
|
let onTimeCount: Int
|
|
let totalCheckIns: Int
|
|
let averageDaysBeforeDeadline: Double?
|
|
let closestCutoffDays: Double?
|
|
let recentMood: MonthlyCheckInMood?
|
|
let achievements: [MonthlyCheckInAchievement]
|
|
|
|
static var empty: MonthlyCheckInStats {
|
|
MonthlyCheckInStats(
|
|
currentStreak: 0,
|
|
bestStreak: 0,
|
|
onTimeCount: 0,
|
|
totalCheckIns: 0,
|
|
averageDaysBeforeDeadline: nil,
|
|
closestCutoffDays: nil,
|
|
recentMood: nil,
|
|
achievements: []
|
|
)
|
|
}
|
|
|
|
var onTimeRate: Double {
|
|
guard totalCheckIns > 0 else { return 0 }
|
|
return Double(onTimeCount) / Double(totalCheckIns)
|
|
}
|
|
}
|