USB-Meter / USB Meter / Views / ChargedDevices / Sidebar / SidebarChargedDevicesSectionView.swift
Newer Older
93 lines | 3.43kb
Bogdan Timofte authored a month ago
1
//
2
//  SidebarChargedDevicesSectionView.swift
3
//  USB Meter
4
//
5
//  Created by Codex on 10/04/2026.
6
//
7

            
8
import SwiftUI
9

            
10
struct SidebarChargedDevicesSectionView: View {
11
    let title: String
Bogdan Timofte authored a month ago
12
    let mode: ChargedDeviceLibraryMode
Bogdan Timofte authored a month ago
13
    let chargedDevices: [ChargedDeviceSummary]
14
    let emptyStateText: String
15
    let tint: Color
Bogdan Timofte authored a month ago
16
    let isExpanded: Bool
17
    let onToggle: () -> Void
Bogdan Timofte authored a month ago
18
    let onAdd: () -> Void
19

            
20
    var body: some View {
21
        Section(header: headerView) {
Bogdan Timofte authored a month ago
22
            if isExpanded {
23
                // Library overview row — navigates to the full management library
24
                NavigationLink(destination: SidebarChargedDeviceLibraryView(mode: mode)) {
25
                    libraryRow
Bogdan Timofte authored a month ago
26
                }
Bogdan Timofte authored a month ago
27
                .buttonStyle(.plain)
Bogdan Timofte authored a month ago
28
                .transition(.opacity.combined(with: .move(edge: .top)))
29

            
30
                ForEach(chargedDevices) { chargedDevice in
Bogdan Timofte authored a month ago
31
                    NavigationLink(destination: ChargedDeviceSettingsView(chargedDeviceID: chargedDevice.id)) {
Bogdan Timofte authored a month ago
32
                        ChargedDeviceSidebarCardView(chargedDevice: chargedDevice)
33
                    }
34
                    .buttonStyle(.plain)
35
                    .transition(.opacity.combined(with: .move(edge: .top)))
36
                }
Bogdan Timofte authored a month ago
37
            }
38
        }
39
    }
40

            
41
    private var libraryRow: some View {
42
        HStack(spacing: 12) {
43
            Image(systemName: mode == .device ? "square.grid.2x2" : "bolt.circle")
44
                .font(.system(size: 16, weight: .semibold))
45
                .foregroundColor(tint)
46
                .frame(width: 36, height: 36)
47
                .background(tint.opacity(0.14))
48
                .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
49

            
50
            VStack(alignment: .leading, spacing: 2) {
51
                Text("All \(title)")
52
                    .font(.subheadline.weight(.semibold))
53
                    .foregroundColor(.primary)
54
                let count = chargedDevices.count
55
                Text("\(count) \(count == 1 ? mode.singularTitle.lowercased() : mode.title.lowercased())")
56
                    .font(.caption)
57
                    .foregroundColor(.secondary)
Bogdan Timofte authored a month ago
58
            }
Bogdan Timofte authored a month ago
59

            
60
            Spacer()
Bogdan Timofte authored a month ago
61
        }
Bogdan Timofte authored a month ago
62
        .padding(.vertical, 4)
Bogdan Timofte authored a month ago
63
    }
64

            
65
    private var headerView: some View {
66
        HStack(alignment: .firstTextBaseline, spacing: 10) {
Bogdan Timofte authored a month ago
67
            Button(action: onToggle) {
68
                HStack(alignment: .firstTextBaseline, spacing: 4) {
69
                    Image(systemName: "chevron.right")
70
                        .font(.caption.weight(.semibold))
71
                        .foregroundColor(.secondary)
72
                        .rotationEffect(.degrees(isExpanded ? 90 : 0))
73
                        .animation(.easeInOut(duration: 0.22), value: isExpanded)
74
                    Text(title)
75
                        .font(.headline)
76
                }
77
            }
78
            .buttonStyle(.plain)
Bogdan Timofte authored a month ago
79
            Spacer()
80
            Button(action: onAdd) {
81
                Image(systemName: "plus.circle.fill")
82
                    .font(.body.weight(.semibold))
83
                    .foregroundColor(tint)
84
            }
85
            .buttonStyle(.plain)
86
            Text("\(chargedDevices.count)")
87
                .font(.caption.weight(.bold))
88
                .padding(.horizontal, 10)
89
                .padding(.vertical, 6)
90
                .meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24, cornerRadius: 999)
91
        }
92
    }
93
}