// // SidebarChargedDevicesSectionView.swift // USB Meter // // Created by Codex on 10/04/2026. // import SwiftUI struct SidebarChargedDevicesSectionView: View { let title: String let mode: ChargedDeviceLibraryMode let chargedDevices: [ChargedDeviceSummary] let emptyStateText: String let tint: Color let isExpanded: Bool let onToggle: () -> Void let onAdd: () -> Void var body: some View { Section(header: headerView) { if isExpanded { // Library overview row — navigates to the full management library NavigationLink(destination: SidebarChargedDeviceLibraryView(mode: mode)) { libraryRow } .buttonStyle(.plain) .transition(.opacity.combined(with: .move(edge: .top))) ForEach(chargedDevices) { chargedDevice in NavigationLink(destination: ChargedDeviceDetailView(chargedDeviceID: chargedDevice.id)) { ChargedDeviceSidebarCardView(chargedDevice: chargedDevice) } .buttonStyle(.plain) .transition(.opacity.combined(with: .move(edge: .top))) } } } } private var libraryRow: some View { HStack(spacing: 12) { Image(systemName: mode == .device ? "square.grid.2x2" : "bolt.circle") .font(.system(size: 16, weight: .semibold)) .foregroundColor(tint) .frame(width: 36, height: 36) .background(tint.opacity(0.14)) .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) VStack(alignment: .leading, spacing: 2) { Text("All \(title)") .font(.subheadline.weight(.semibold)) .foregroundColor(.primary) let count = chargedDevices.count Text("\(count) \(count == 1 ? mode.singularTitle.lowercased() : mode.title.lowercased())") .font(.caption) .foregroundColor(.secondary) } Spacer() } .padding(.vertical, 4) } private var headerView: some View { HStack(alignment: .firstTextBaseline, spacing: 10) { Button(action: onToggle) { HStack(alignment: .firstTextBaseline, spacing: 4) { Image(systemName: "chevron.right") .font(.caption.weight(.semibold)) .foregroundColor(.secondary) .rotationEffect(.degrees(isExpanded ? 90 : 0)) .animation(.easeInOut(duration: 0.22), value: isExpanded) Text(title) .font(.headline) } } .buttonStyle(.plain) Spacer() Button(action: onAdd) { Image(systemName: "plus.circle.fill") .font(.body.weight(.semibold)) .foregroundColor(tint) } .buttonStyle(.plain) Text("\(chargedDevices.count)") .font(.caption.weight(.bold)) .padding(.horizontal, 10) .padding(.vertical, 6) .meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24, cornerRadius: 999) } } } private struct ChargedDeviceSidebarCardView: View { let chargedDevice: ChargedDeviceSummary var body: some View { HStack(alignment: .top, spacing: 12) { ChargedDeviceQRCodeView(qrIdentifier: chargedDevice.qrIdentifier, side: 54) VStack(alignment: .leading, spacing: 6) { HStack { ChargedDeviceIdentityLabelView( chargedDevice: chargedDevice, iconPointSize: 17 ) .font(.headline) if chargedDevice.activeSession != nil { Spacer() Text("Live") .font(.caption.weight(.bold)) .foregroundColor(.green) } } Text(chargedDevice.identityTitle) .font(.caption.weight(.semibold)) .foregroundColor(.secondary) if chargedDevice.isCharger { if let chargerMaximumPowerWatts = chargedDevice.chargerMaximumPowerWatts { Text("Max power: \(chargerMaximumPowerWatts.format(decimalDigits: 2)) W") .font(.caption2) .foregroundColor(.secondary) } else { Text("Wireless charger") .font(.caption2) .foregroundColor(.secondary) } } else { Text(chargedDevice.supportedChargingModes.map(\.title).joined(separator: " + ")) .font(.caption2) .foregroundColor(.secondary) if let estimatedCapacityWh = chargedDevice.estimatedBatteryCapacityWh { Text("Capacity: \(estimatedCapacityWh.format(decimalDigits: 2)) Wh") .font(.caption2) .foregroundColor(.secondary) } else { Text("Capacity: learning") .font(.caption2) .foregroundColor(.secondary) } } } } .padding(.vertical, 4) } }