Add lead workflows, PDF signing, AR projects and photo gallery integration
This commit is contained in:
91
GasTankAR/Views/Leads/Detail/LeadLocationSection.swift
Normal file
91
GasTankAR/Views/Leads/Detail/LeadLocationSection.swift
Normal file
@ -0,0 +1,91 @@
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
|
||||
struct LeadLocationSection: View {
|
||||
let name: String
|
||||
let address: LeadAddress
|
||||
var locationService: any CustomerLocationService = AppleMapsCustomerLocationService()
|
||||
@State private var coordinate: CLLocationCoordinate2D?
|
||||
@State private var position: MapCameraPosition = .automatic
|
||||
@State private var errorMessage: LocalizedStringResource?
|
||||
@State private var retryID = 0
|
||||
|
||||
static let mapHeight: CGFloat = 328
|
||||
|
||||
private var addressText: String {
|
||||
[address.street, "\(address.postalCode) \(address.city)"]
|
||||
.compactMap { $0 }
|
||||
.joined(separator: ", ")
|
||||
}
|
||||
|
||||
private var mapsURL: URL? {
|
||||
var components = URLComponents(string: "https://maps.apple.com/")
|
||||
components?.queryItems = [URLQueryItem(name: "q", value: addressText)]
|
||||
return components?.url
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
LeadSectionHeading(title: "STANDORT")
|
||||
ZStack {
|
||||
LeadDetailStyle.card
|
||||
if let coordinate {
|
||||
Map(position: $position) {
|
||||
Marker(name, coordinate: coordinate)
|
||||
.tint(LeadDetailStyle.blue)
|
||||
}
|
||||
.mapStyle(.standard(pointsOfInterest: .excludingAll))
|
||||
.accessibilityLabel("Standort von \(name), \(addressText)")
|
||||
} else if let errorMessage {
|
||||
ContentUnavailableView {
|
||||
Label("Standort nicht verfügbar", systemImage: "mappin.slash")
|
||||
} description: {
|
||||
Text(errorMessage)
|
||||
} actions: {
|
||||
Button("Erneut versuchen") { retryID += 1 }
|
||||
}
|
||||
} else {
|
||||
ProgressView("Standort wird geladen")
|
||||
}
|
||||
}
|
||||
.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||
if let mapsURL {
|
||||
Link(destination: mapsURL) {
|
||||
Label("In Apple Maps öffnen", systemImage: "map")
|
||||
.font(.subheadline.weight(.semibold))
|
||||
.frame(maxWidth: .infinity, minHeight: 48)
|
||||
.foregroundStyle(.white)
|
||||
.background(LeadDetailStyle.blue)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(height: Self.mapHeight)
|
||||
.clipShape(.rect(cornerRadius: 12))
|
||||
}
|
||||
.task(id: addressText + "#\(retryID)") {
|
||||
coordinate = nil
|
||||
errorMessage = nil
|
||||
do {
|
||||
let result = try await locationService.coordinate(for: addressText)
|
||||
try Task.checkCancellation()
|
||||
position = .region(MKCoordinateRegion(
|
||||
center: result, latitudinalMeters: 800, longitudinalMeters: 800
|
||||
))
|
||||
coordinate = result
|
||||
} catch is CancellationError {
|
||||
} catch {
|
||||
guard !Task.isCancelled else { return }
|
||||
if error is CustomerLocationError {
|
||||
errorMessage = "Für diese Anschrift wurde kein Standort gefunden."
|
||||
} else if let networkError = error as? URLError,
|
||||
[.notConnectedToInternet, .networkConnectionLost, .timedOut].contains(networkError.code) {
|
||||
errorMessage = "Keine Verbindung zu Apple Maps. Bitte prüfe deine Internetverbindung und versuche es erneut."
|
||||
} else {
|
||||
errorMessage = "Apple Maps konnte den Standort gerade nicht ermitteln. Bitte versuche es erneut."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user