payfrit-beacon-ios/PayfritBeacon/BusinessListView.swift
John Pinkyfloyd 8c2320da44 Add ios-marketing idiom, iPad orientations, launch screen
- 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>
2026-02-10 19:38:11 -08:00

144 lines
4.7 KiB
Swift

import SwiftUI
import Kingfisher
struct BusinessListView: View {
@Binding var hasAutoSelected: Bool
var onBusinessSelected: (Business) -> Void
var onLogout: () -> Void
@State private var businesses: [Business] = []
@State private var isLoading = false
@State private var errorMessage: String?
var body: some View {
NavigationStack {
VStack {
if isLoading {
Spacer()
ProgressView("Loading businesses...")
Spacer()
} else if let error = errorMessage {
Spacer()
Text(error)
.foregroundColor(.errorRed)
.multilineTextAlignment(.center)
.padding()
addBusinessButton
Spacer()
} else if businesses.isEmpty {
Spacer()
Text("No businesses found")
.foregroundColor(.secondary)
addBusinessButton
Spacer()
} else {
List(businesses) { business in
Button {
onBusinessSelected(business)
} label: {
businessRow(business)
}
.buttonStyle(.plain)
}
.listStyle(.plain)
addBusinessButton
}
}
.navigationTitle("Select Business")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Log Out") {
logout()
}
}
}
}
.onAppear {
loadBusinesses()
}
}
private func businessRow(_ business: Business) -> some View {
HStack(spacing: 12) {
if let ext = business.headerImageExtension, !ext.isEmpty {
let baseDomain = Api.IS_DEV ? "https://dev.payfrit.com" : "https://biz.payfrit.com"
let imageUrl = URL(string: "\(baseDomain)/uploads/businesses/\(business.businessId)/header.\(ext)")
KFImage(imageUrl)
.resizable()
.placeholder {
Image(systemName: "building.2")
.font(.title2)
.foregroundColor(.secondary)
}
.scaledToFill()
.frame(width: 48, height: 48)
.clipShape(Circle())
} else {
Image(systemName: "building.2")
.font(.title2)
.foregroundColor(.secondary)
.frame(width: 48, height: 48)
}
VStack(alignment: .leading, spacing: 2) {
Text(business.name)
.font(.body.weight(.medium))
.foregroundColor(.primary)
Text("Tap to configure beacons")
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.secondary)
.font(.caption)
}
.padding(.vertical, 4)
}
private var addBusinessButton: some View {
Button {
let baseDomain = Api.IS_DEV ? "https://dev.payfrit.com" : "https://biz.payfrit.com"
if let url = URL(string: "\(baseDomain)/portal/index.html") {
UIApplication.shared.open(url)
}
} label: {
Text("Add Business via Portal")
.font(.callout)
.foregroundColor(.payfritGreen)
}
.padding()
}
private func loadBusinesses() {
isLoading = true
errorMessage = nil
Task {
do {
let result = try await Api.shared.listBusinesses()
businesses = result
isLoading = false
if businesses.count == 1 && !hasAutoSelected {
hasAutoSelected = true
onBusinessSelected(businesses[0])
}
} catch {
isLoading = false
errorMessage = error.localizedDescription
}
}
}
private func logout() {
UserDefaults.standard.removeObject(forKey: "token")
UserDefaults.standard.removeObject(forKey: "userId")
UserDefaults.standard.removeObject(forKey: "firstName")
Api.shared.setAuthToken(nil)
onLogout()
}
}