import SwiftUI // MARK: - BlackRoad Brand Colors (iOS) extension Color { static let brHotPink = Color(red: 1.0, green: 0.114, blue: 0.424) static let brAmber = Color(red: 0.961, green: 0.651, blue: 0.137) static let brElectricBlue = Color(red: 0.161, green: 0.475, blue: 1.0) static let brViolet = Color(red: 0.612, green: 0.153, blue: 0.690) } // MARK: - iOS Bridge View struct iOSContentView: View { @EnvironmentObject var udp: BlackRoadUDPManager var body: some View { NavigationView { ScrollView { VStack(spacing: 20) { // Connection Status Card connectionCard // Data Preview if udp.isConnected { sensorCard aiCard fleetCard } } .padding() } .background(Color.black) .navigationTitle("BlackRoad Watch") .navigationBarTitleDisplayMode(.inline) .toolbarColorScheme(.dark, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(Color.black, for: .navigationBar) } .preferredColorScheme(.dark) } // MARK: - Connection Card private var connectionCard: some View { VStack(spacing: 12) { HStack { Text("BLACKROAD") .font(.system(size: 13, weight: .black, design: .monospaced)) .foregroundStyle( LinearGradient( colors: [.brAmber, .brHotPink], startPoint: .leading, endPoint: .trailing ) ) Spacer() Text("BRIDGE") .font(.system(size: 11, weight: .bold, design: .monospaced)) .foregroundColor(.gray) } Divider().background(Color.gray.opacity(0.3)) // M1s Connection HStack { Circle() .fill(udp.isConnected ? Color.green : Color.red) .frame(width: 10, height: 10) Text("M1s Dock") .font(.system(size: 14, weight: .medium)) .foregroundColor(.white) Spacer() if udp.isConnected { Text(udp.sourceAddress) .font(.system(size: 12, design: .monospaced)) .foregroundColor(.gray) } else { Text(udp.isListening ? "Listening on :8420" : "Starting...") .font(.system(size: 12, design: .monospaced)) .foregroundColor(.gray) } } // Apple Watch Connection HStack { Circle() .fill(udp.watchReachable ? Color.green : Color.orange) .frame(width: 10, height: 10) Text("Apple Watch") .font(.system(size: 14, weight: .medium)) .foregroundColor(.white) Spacer() Text(udp.watchReachable ? "Connected" : "Waiting") .font(.system(size: 12, design: .monospaced)) .foregroundColor(.gray) } // Stats HStack { Label("\(udp.packetsReceived)", systemImage: "arrow.down.circle") .font(.system(size: 12, design: .monospaced)) .foregroundColor(.brElectricBlue) Spacer() if let last = udp.lastUpdate { Text(last, style: .relative) .font(.system(size: 12)) .foregroundColor(.gray) } } } .padding() .background( RoundedRectangle(cornerRadius: 16) .fill(Color.white.opacity(0.05)) .overlay( RoundedRectangle(cornerRadius: 16) .strokeBorder( LinearGradient( colors: [.brAmber.opacity(0.5), .brHotPink.opacity(0.3)], startPoint: .topLeading, endPoint: .bottomTrailing ), lineWidth: 1 ) ) ) } // MARK: - Sensor Card private var sensorCard: some View { VStack(alignment: .leading, spacing: 8) { Label("SENSORS", systemImage: "thermometer") .font(.system(size: 11, weight: .bold, design: .monospaced)) .foregroundColor(.brAmber) if let s = udp.sensorData { dataRow("Temperature", String(format: "%.1f\u{00B0}C", s.temperature), .brAmber) dataRow("Humidity", String(format: "%.1f%%", s.humidity), .brElectricBlue) dataRow("Battery", "\(s.batteryMV)mV", s.batteryMV > 3500 ? .green : .red) dataRow("Uptime", formatUptime(s.uptimeSec), .gray) } } .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(RoundedRectangle(cornerRadius: 16).fill(Color.white.opacity(0.05))) } // MARK: - AI Card private var aiCard: some View { VStack(alignment: .leading, spacing: 8) { Label("NPU", systemImage: "brain") .font(.system(size: 11, weight: .bold, design: .monospaced)) .foregroundColor(.brViolet) if let a = udp.aiStatus { dataRow("Load", "\(a.npuLoad)%", .brElectricBlue) dataRow("Temp", "\(a.npuTemp)\u{00B0}C", a.npuTemp > 70 ? .red : .brAmber) dataRow("Confidence", "\(a.confidence)%", .brHotPink) dataRow("Inferences", "\(a.totalInferences)", .brAmber) } } .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(RoundedRectangle(cornerRadius: 16).fill(Color.white.opacity(0.05))) } // MARK: - Fleet Card private var fleetCard: some View { VStack(alignment: .leading, spacing: 8) { Label("FLEET", systemImage: "server.rack") .font(.system(size: 11, weight: .bold, design: .monospaced)) .foregroundColor(.brHotPink) if let h = udp.systemHealth { dataRow("Devices", "\(h.fleetOnline)/\(h.fleetTotal)", .brElectricBlue) dataRow("Agents", "\(h.agentsActive)", .brViolet) dataRow("Green", "\(h.trafficGreen)", .green) dataRow("Tasks Done", "\(h.tasksDone)", .green) dataRow("Repos", "\(h.reposCount)", .brAmber) dataRow("CF Projects", "\(h.cfProjects)", .brElectricBlue) dataRow("Memory", "\(h.memoryEntries)", .brViolet) } } .frame(maxWidth: .infinity, alignment: .leading) .padding() .background(RoundedRectangle(cornerRadius: 16).fill(Color.white.opacity(0.05))) } // MARK: - Helpers private func dataRow(_ label: String, _ value: String, _ color: Color) -> some View { HStack { Text(label) .font(.system(size: 13)) .foregroundColor(.gray) Spacer() Text(value) .font(.system(size: 13, weight: .semibold, design: .monospaced)) .foregroundColor(color) } } private func formatUptime(_ seconds: UInt32) -> String { let h = seconds / 3600 let m = (seconds % 3600) / 60 let s = seconds % 60 return String(format: "%02d:%02d:%02d", h, m, s) } } #Preview { iOSContentView() .environmentObject(BlackRoadUDPManager.shared) }