summaryrefslogtreecommitdiff
path: root/Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-12 00:15:13 -0500
committerChristian Cleberg <[email protected]>2026-04-12 00:15:13 -0500
commitcb1ea5ea4f163d87053285d3fb7999b12a3558b9 (patch)
tree84b562d12e642ff494194387b1b4e1d15b065eb0 /Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift
parent1c5a417277d986ee6fb7dc9dff0332338bdf6f3e (diff)
downloadhutch-2.13.1.tar.gz
hutch-2.13.1.tar.bz2
hutch-2.13.1.zip
harden system status and app reliabilityv2.13.1
Diffstat (limited to 'Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift')
-rw-r--r--Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift119
1 files changed, 119 insertions, 0 deletions
diff --git a/Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift b/Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift
new file mode 100644
index 0000000..5d94dad
--- /dev/null
+++ b/Hutch/Views/SystemStatus/SystemStatusSummaryRow.swift
@@ -0,0 +1,119 @@
+import SwiftUI
+
+struct SystemStatusSummaryRow: View {
+ let title: String
+ let snapshot: SystemStatusSnapshot?
+ let isLoading: Bool
+ let errorMessage: String?
+ let isShowingStaleData: Bool
+
+ init(
+ title: String = "System Status",
+ snapshot: SystemStatusSnapshot?,
+ isLoading: Bool = false,
+ errorMessage: String? = nil,
+ isShowingStaleData: Bool = false
+ ) {
+ self.title = title
+ self.snapshot = snapshot
+ self.isLoading = isLoading
+ self.errorMessage = errorMessage
+ self.isShowingStaleData = isShowingStaleData
+ }
+
+ var body: some View {
+ HStack(spacing: 12) {
+ icon
+ .frame(width: 20)
+
+ VStack(alignment: .leading, spacing: 3) {
+ Text(title)
+ .font(.subheadline.weight(.semibold))
+ .foregroundStyle(.primary)
+
+ Text(primaryMessage)
+ .font(.caption)
+ .foregroundStyle(primaryMessageColor)
+ .lineLimit(2)
+
+ if let metadataMessage {
+ Text(metadataMessage)
+ .font(.caption2)
+ .foregroundStyle(.tertiary)
+ .lineLimit(1)
+ }
+ }
+
+ Spacer(minLength: 8)
+ }
+ .padding(.vertical, 4)
+ .contentShape(Rectangle())
+ }
+
+ @ViewBuilder
+ private var icon: some View {
+ if isLoading && snapshot == nil {
+ ProgressView()
+ .controlSize(.small)
+ } else {
+ Image(systemName: iconName)
+ .foregroundStyle(iconColor)
+ }
+ }
+
+ private var primaryMessage: String {
+ if let snapshot {
+ return snapshot.hasDisruption ? snapshot.bannerSummary : snapshot.overallStatusText
+ }
+ if let errorMessage, !errorMessage.isEmpty {
+ return errorMessage
+ }
+ if isLoading {
+ return "Loading system status…"
+ }
+ return "System status is unavailable right now."
+ }
+
+ private var metadataMessage: String? {
+ if let snapshot {
+ if isShowingStaleData {
+ return "Updated \(snapshot.lastUpdated.relativeDescription) • Showing saved data"
+ }
+ return "Updated \(snapshot.lastUpdated.relativeDescription)"
+ }
+ if errorMessage != nil {
+ return "Open System Status to retry."
+ }
+ return nil
+ }
+
+ private var iconName: String {
+ if let snapshot {
+ return snapshot.hasDisruption ? "exclamationmark.triangle.fill" : "checkmark.circle.fill"
+ }
+ if errorMessage != nil {
+ return "exclamationmark.triangle"
+ }
+ return "server.rack"
+ }
+
+ private var iconColor: Color {
+ if let snapshot {
+ return snapshot.hasDisruption ? .orange : .green
+ }
+ if errorMessage != nil {
+ return .secondary
+ }
+ return .secondary
+ }
+
+ private var primaryMessageColor: Color {
+ if snapshot != nil {
+ return .secondary
+ }
+ if errorMessage != nil {
+ return .secondary
+ }
+ return .secondary
+ }
+}