feat: Full redesign — glassmorphism, weekly charts, HealthKit sync, toast notifications

- DashboardView: полный редизайн с приветствием по времени суток, pull-to-refresh
- ReadinessCardView: анимированное кольцо, цветные факторы с иконками
- MetricCardView: glassmorphism карточки, градиентные иконки, SleepCard/StepsCard
- WeeklyChartView: bar chart (Sleep/HRV/Steps) без внешних библиотек
- ToastView: уведомления об успехе/ошибке с автоскрытием
- HealthKitService: полный сбор метрик + отправка на сервер
- HealthModels: HeatmapEntry для недельных данных
- Тёмная тема #0a0a1a, haptic feedback, анимации появления
This commit is contained in:
Cosmo
2026-03-25 11:13:20 +00:00
parent 14fcf7f770
commit 1eafeec5fe
8 changed files with 1230 additions and 105 deletions

View File

@@ -1,19 +1,85 @@
import Foundation
struct ReadinessResponse: Codable {
let score: Int; let status: String; let recommendation: String
let date: String?; let factors: ReadinessFactors?
let score: Int
let status: String
let recommendation: String
let date: String?
let factors: ReadinessFactors?
}
struct ReadinessFactors: Codable {
let sleep: FactorScore; let hrv: FactorScore; let rhr: FactorScore; let activity: FactorScore
let sleep: FactorScore
let hrv: FactorScore
let rhr: FactorScore
let activity: FactorScore
}
struct FactorScore: Codable { let score: Int; let value: String; let baseline: String? }
struct FactorScore: Codable {
let score: Int
let value: String
let baseline: String?
}
struct LatestHealthResponse: Codable {
let sleep: SleepData?; let heartRate: HeartRateData?; let restingHeartRate: RestingHRData?
let hrv: HRVData?; let steps: StepsData?; let activeEnergy: EnergyData?
let sleep: SleepData?
let heartRate: HeartRateData?
let restingHeartRate: RestingHRData?
let hrv: HRVData?
let steps: StepsData?
let activeEnergy: EnergyData?
}
struct SleepData: Codable {
let totalSleep: Double?
let deep: Double?
let rem: Double?
let core: Double?
}
struct HeartRateData: Codable {
let avg: Int?
let min: Int?
let max: Int?
}
struct RestingHRData: Codable {
let value: Double?
}
struct HRVData: Codable {
let avg: Double?
let latest: Double?
}
struct StepsData: Codable {
let total: Int?
}
struct EnergyData: Codable {
let total: Int?
let units: String?
}
// MARK: - Heatmap / Weekly Data
struct HeatmapEntry: Codable, Identifiable {
let date: String
let score: Int?
let steps: Int?
let sleep: Double?
let hrv: Double?
let rhr: Double?
var id: String { date }
var displayDate: String {
let parts = date.split(separator: "-")
guard parts.count == 3 else { return date }
return "\(parts[2]).\(parts[1])"
}
}
struct HeatmapResponse: Codable {
let data: [HeatmapEntry]
}
struct SleepData: Codable { let totalSleep: Double?; let deep: Double?; let rem: Double?; let core: Double? }
struct HeartRateData: Codable { let avg: Int?; let min: Int?; let max: Int? }
struct RestingHRData: Codable { let value: Double? }
struct HRVData: Codable { let avg: Double?; let latest: Double? }
struct StepsData: Codable { let total: Int? }
struct EnergyData: Codable { let total: Int?; let units: String? }