import SwiftUI struct DashboardView: View { @Environment(DeviceStore.self) private var store @Environment(BluetoothManager.self) private var bluetooth @State private var isAddingDevice = false @State private var isManagingProfiles = false private let columns = [GridItem(.adaptive(minimum: 300), spacing: 16)] var body: some View { NavigationStack { ScrollView { if !bluetooth.isBluetoothReady { statusBanner } if store.activeDevices.isEmpty { emptyState } else { LazyVGrid(columns: columns, spacing: 16) { ForEach(store.activeDevices) { device in NavigationLink { DeviceDetailView(device: device) } label: { DeviceCard( device: device, snapshot: bluetooth.snapshots[device.id], linkState: bluetooth.linkStates[device.id] ?? .searching ) } .buttonStyle(.plain) } } .padding(.horizontal) .padding(.top, 8) } } .background(Color(.systemGroupedBackground)) .navigationTitle(store.activeProfile?.name ?? "Camper") .toolbar { ToolbarItem(placement: .topBarLeading) { profileMenu } ToolbarItem(placement: .primaryAction) { Button("Gerät hinzufügen", systemImage: "plus") { isAddingDevice = true } } } .sheet(isPresented: $isAddingDevice) { AddDeviceView() } .sheet(isPresented: $isManagingProfiles) { ProfilesView() } } } /// Umschalter zwischen den Fahrzeugen. private var profileMenu: some View { Menu { Picker("Fahrzeug", selection: Binding( get: { store.activeProfileID }, set: { id in guard let profile = store.profiles.first(where: { $0.id == id }) else { return } store.selectProfile(profile) bluetooth.refreshConfiguration() } )) { ForEach(store.profiles) { profile in Label(profile.name, systemImage: profile.symbol).tag(profile.id) } } Divider() Button("Fahrzeuge verwalten…", systemImage: "gearshape") { isManagingProfiles = true } } label: { Label(store.activeProfile?.name ?? "Fahrzeug", systemImage: store.activeProfile?.symbol ?? "box.truck") .labelStyle(.iconOnly) } } private var statusBanner: some View { Label(bluetooth.bluetoothStatusText, systemImage: "exclamationmark.triangle.fill") .font(.callout) .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(.orange.opacity(0.15), in: .rect(cornerRadius: 12)) .padding(.horizontal) .padding(.top, 8) } private var emptyState: some View { ContentUnavailableView { Label("Noch keine Geräte", systemImage: "antenna.radiowaves.left.and.right") } description: { Text("Füge \(store.activeProfile.map { "„\($0.name)“" } ?? "diesem Fahrzeug") " + "den Ladebooster, den Solarladeregler und das BMS hinzu.") } actions: { Button("Gerät suchen") { isAddingDevice = true } .buttonStyle(.borderedProminent) } .padding(.top, 60) } }