83 lines
2.3 KiB
Swift
83 lines
2.3 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
import Combine
|
|
@MainActor
|
|
final class DashboardViewModel: ViewModel {
|
|
|
|
@Published private(set) var prescriptions: [PrescriptionWithSchedulesResponse] = []
|
|
@Published private(set) var medicationNames: [String: String] = [:]
|
|
@Published private(set) var errorMessage: String?
|
|
|
|
private let api: MedMapAPI
|
|
|
|
init(api: MedMapAPI = MedMapAPI()) {
|
|
self.api = api
|
|
super.init()
|
|
}
|
|
|
|
var nextDose: DashboardDose? {
|
|
scheduledDoses.first(where: { $0.time >= currentTime }) ?? scheduledDoses.first
|
|
}
|
|
|
|
var scheduledDoses: [DashboardDose] {
|
|
prescriptions.flatMap { response in
|
|
response.schedules.flatMap { schedule in
|
|
schedule.timesOfDay.map { time in
|
|
DashboardDose(
|
|
time: time,
|
|
title: medicationNames[response.medicationId] ?? "Medicacao prescrita",
|
|
detail: response.prescription.instructions ?? doseDescription(schedule)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
.sorted { $0.time < $1.time }
|
|
}
|
|
|
|
func loadDashboard() async {
|
|
guard !isLoading else { return }
|
|
|
|
isLoading = true
|
|
errorMessage = nil
|
|
defer { isLoading = false }
|
|
|
|
do {
|
|
async let activePrescriptions = api.listMyActivePrescriptions()
|
|
async let medications = api.listMedications()
|
|
|
|
let (prescriptions, medicationResponse) = try await (activePrescriptions, medications)
|
|
self.prescriptions = prescriptions
|
|
medicationNames = Dictionary(
|
|
uniqueKeysWithValues: medicationResponse.medications.map { ($0.medicationId, $0.name) }
|
|
)
|
|
} catch {
|
|
errorMessage = "Nao foi possivel carregar a sua medicacao."
|
|
fluxlog("Patient dashboard load failed: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
|
|
private var currentTime: String {
|
|
let formatter = DateFormatter()
|
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
formatter.dateFormat = "HH:mm"
|
|
return formatter.string(from: .now)
|
|
}
|
|
|
|
private func doseDescription(_ schedule: PrescriptionScheduleResponse) -> String {
|
|
guard let amount = schedule.doseAmount else { return "Dose conforme prescricao" }
|
|
let formattedAmount = amount.formatted(.number.precision(.fractionLength(0...2)))
|
|
return schedule.doseUnit.map { "\(formattedAmount) \($0)" } ?? formattedAmount
|
|
}
|
|
}
|
|
|
|
struct DashboardDose: Identifiable {
|
|
let time: String
|
|
let title: String
|
|
let detail: String
|
|
|
|
var id: String { "\(time)-\(title)-\(detail)" }
|
|
}
|
|
// Created by RSA on 28/08/2026.
|
|
//
|
|
|