| 1 |
// |
|
| 2 |
// SidebarPowerbanksSectionView.swift |
|
| 3 |
// USB Meter |
|
| 4 |
// |
|
| 5 | ||
| 6 |
import SwiftUI |
|
| 7 | ||
| 8 |
struct SidebarPowerbanksSectionView: View {
|
|
| 9 |
let title: String |
|
| 10 |
let powerbanks: [PowerbankSummary] |
|
| 11 |
let emptyStateText: String |
|
| 12 |
let tint: Color |
|
| 13 |
let isExpanded: Bool |
|
| 14 |
let onToggle: () -> Void |
|
| 15 |
let onAdd: () -> Void |
|
| 16 | ||
| 17 |
var body: some View {
|
|
| 18 |
Section(header: headerView) {
|
|
| 19 |
if isExpanded {
|
|
| 20 |
ForEach(powerbanks) { powerbank in
|
|
| 21 |
NavigationLink(destination: PowerbankDetailView(powerbankID: powerbank.id)) {
|
|
| 22 |
PowerbankSidebarCardView(powerbank: powerbank) |
|
| 23 |
} |
|
| 24 |
.buttonStyle(.plain) |
|
| 25 |
.transition(.opacity.combined(with: .move(edge: .top))) |
|
| 26 |
} |
|
| 27 | ||
| 28 |
if powerbanks.isEmpty {
|
|
| 29 |
Text(emptyStateText) |
|
| 30 |
.font(.caption) |
|
| 31 |
.foregroundColor(.secondary) |
|
| 32 |
.padding(.vertical, 6) |
|
| 33 |
.transition(.opacity) |
|
| 34 |
} |
|
| 35 |
} |
|
| 36 |
} |
|
| 37 |
} |
|
| 38 | ||
| 39 |
private var headerView: some View {
|
|
| 40 |
HStack(alignment: .firstTextBaseline, spacing: 10) {
|
|
| 41 |
Button(action: onToggle) {
|
|
| 42 |
HStack(alignment: .firstTextBaseline, spacing: 4) {
|
|
| 43 |
Image(systemName: "chevron.right") |
|
| 44 |
.font(.caption.weight(.semibold)) |
|
| 45 |
.foregroundColor(.secondary) |
|
| 46 |
.rotationEffect(.degrees(isExpanded ? 90 : 0)) |
|
| 47 |
.animation(.easeInOut(duration: 0.22), value: isExpanded) |
|
| 48 |
Text(title) |
|
| 49 |
.font(.headline) |
|
| 50 |
} |
|
| 51 |
} |
|
| 52 |
.buttonStyle(.plain) |
|
| 53 |
Spacer() |
|
| 54 |
Button(action: onAdd) {
|
|
| 55 |
Image(systemName: "plus.circle.fill") |
|
| 56 |
.font(.body.weight(.semibold)) |
|
| 57 |
.foregroundColor(tint) |
|
| 58 |
} |
|
| 59 |
.buttonStyle(.plain) |
|
| 60 |
Text("\(powerbanks.count)")
|
|
| 61 |
.font(.caption.weight(.bold)) |
|
| 62 |
.padding(.horizontal, 10) |
|
| 63 |
.padding(.vertical, 6) |
|
| 64 |
.meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24, cornerRadius: 999) |
|
| 65 |
} |
|
| 66 |
} |
|
| 67 |
} |