- Fixed App Store icon display with ios-marketing idiom - Added iPad orientation support for multitasking - Added UILaunchScreen for iPad requirements - Removed unused BLE permissions and files from build Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
83 lines
2.8 KiB
Swift
83 lines
2.8 KiB
Swift
import SwiftUI
|
|
|
|
struct BeaconEditSheet: View {
|
|
var onSaved: () -> Void
|
|
|
|
@State private var name = ""
|
|
@State private var uuid = ""
|
|
@State private var isSaving = false
|
|
@State private var error: String?
|
|
@EnvironmentObject var appState: AppState
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
Form {
|
|
Section("New Beacon") {
|
|
TextField("Name (e.g. Table 1 Beacon)", text: $name)
|
|
TextField("UUID (32 hex characters)", text: $uuid)
|
|
.textInputAutocapitalization(.characters)
|
|
.autocorrectionDisabled()
|
|
.font(.system(.body, design: .monospaced))
|
|
}
|
|
|
|
Section {
|
|
Text("The UUID should be a 32-character hexadecimal string that uniquely identifies this beacon. Example: 626C7565636861726D31000000000001")
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
|
|
if let error = error {
|
|
Section {
|
|
HStack {
|
|
Image(systemName: "exclamationmark.circle.fill")
|
|
.foregroundColor(.red)
|
|
Text(error)
|
|
.foregroundColor(.red)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Add Beacon")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Cancel") { dismiss() }
|
|
}
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
Button("Save") { save() }
|
|
.disabled(isSaving || name.isEmpty || uuid.isEmpty)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func save() {
|
|
let trimmedName = name.trimmingCharacters(in: .whitespaces)
|
|
let trimmedUUID = uuid.trimmingCharacters(in: .whitespaces)
|
|
|
|
guard !trimmedName.isEmpty else {
|
|
error = "Name is required"
|
|
return
|
|
}
|
|
guard !trimmedUUID.isEmpty else {
|
|
error = "UUID is required"
|
|
return
|
|
}
|
|
|
|
isSaving = true
|
|
error = nil
|
|
Task {
|
|
do {
|
|
_ = try await APIService.shared.createBeacon(name: trimmedName, uuid: trimmedUUID)
|
|
onSaved()
|
|
dismiss()
|
|
} catch let apiError as APIError where apiError == .unauthorized {
|
|
await appState.handleUnauthorized()
|
|
} catch {
|
|
self.error = error.localizedDescription
|
|
}
|
|
isSaving = false
|
|
}
|
|
}
|
|
}
|