1 contributor
//
// SidebarHelpSectionView.swift
// USB Meter
//
import SwiftUI
struct SidebarHelpSectionView<BluetoothHelpDestination: View, DeviceHelpDestination: View>: View {
let activeReason: SidebarHelpReason?
let isExpanded: Bool
let bluetoothStatusTint: Color
let bluetoothStatusText: String
let cloudSyncHelpTitle: String
let cloudSyncHelpMessage: String
let onToggle: () -> Void
let onOpenSettings: () -> Void
let bluetoothHelpDestination: BluetoothHelpDestination
let deviceHelpDestination: DeviceHelpDestination
init(
activeReason: SidebarHelpReason?,
isExpanded: Bool,
bluetoothStatusTint: Color,
bluetoothStatusText: String,
cloudSyncHelpTitle: String,
cloudSyncHelpMessage: String,
onToggle: @escaping () -> Void,
onOpenSettings: @escaping () -> Void,
@ViewBuilder bluetoothHelpDestination: () -> BluetoothHelpDestination,
@ViewBuilder deviceHelpDestination: () -> DeviceHelpDestination
) {
self.activeReason = activeReason
self.isExpanded = isExpanded
self.bluetoothStatusTint = bluetoothStatusTint
self.bluetoothStatusText = bluetoothStatusText
self.cloudSyncHelpTitle = cloudSyncHelpTitle
self.cloudSyncHelpMessage = cloudSyncHelpMessage
self.onToggle = onToggle
self.onOpenSettings = onOpenSettings
self.bluetoothHelpDestination = bluetoothHelpDestination()
self.deviceHelpDestination = deviceHelpDestination()
}
var body: some View {
Section(header: Text("Help & Troubleshooting").font(.headline)) {
Button(action: onToggle) {
HStack(spacing: 14) {
Image(systemName: sectionSymbol)
.font(.system(size: 18, weight: .semibold))
.foregroundColor(sectionTint)
.frame(width: 42, height: 42)
.background(Circle().fill(sectionTint.opacity(0.18)))
Text("Help")
.font(.headline)
Spacer()
if let activeReason {
Text(activeReason.badgeTitle)
.font(.caption2.weight(.bold))
.foregroundColor(activeReason.tint)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(
Capsule(style: .continuous)
.fill(activeReason.tint.opacity(0.12))
)
.overlay(
Capsule(style: .continuous)
.stroke(activeReason.tint.opacity(0.22), lineWidth: 1)
)
}
Image(systemName: isExpanded ? "chevron.up" : "chevron.down")
.font(.footnote.weight(.bold))
.foregroundColor(.secondary)
}
.padding(14)
.meterCard(tint: sectionTint, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 18)
}
.buttonStyle(.plain)
if isExpanded {
if let activeReason {
SidebarHelpNoticeCardView(
reason: activeReason,
cloudSyncHelpTitle: cloudSyncHelpTitle,
cloudSyncHelpMessage: cloudSyncHelpMessage
)
}
SidebarBluetoothStatusCardView(
tint: bluetoothStatusTint,
statusText: bluetoothStatusText
)
if activeReason == .cloudSyncUnavailable {
Button(action: onOpenSettings) {
SidebarLinkCardView(
title: "Open Settings",
subtitle: "Check Apple ID, iCloud Drive, and any restrictions affecting Cloud sync.",
symbol: "gearshape.fill",
tint: .indigo
)
}
.buttonStyle(.plain)
}
NavigationLink(destination: bluetoothHelpDestination) {
SidebarLinkCardView(
title: "Bluetooth",
subtitle: "Permissions, adapter state, and connection tips.",
symbol: "bolt.horizontal.circle.fill",
tint: bluetoothStatusTint
)
}
.buttonStyle(.plain)
NavigationLink(destination: deviceHelpDestination) {
SidebarLinkCardView(
title: "Device",
subtitle: "Quick checks when a meter is not responding as expected.",
symbol: "questionmark.circle.fill",
tint: .orange
)
}
.buttonStyle(.plain)
}
}
.animation(.easeInOut(duration: 0.22), value: isExpanded)
}
private var sectionTint: Color {
activeReason?.tint ?? .secondary
}
private var sectionSymbol: String {
activeReason?.symbol ?? "questionmark.circle.fill"
}
}