Add lead workflows, PDF signing, AR projects and photo gallery integration

This commit is contained in:
Dennis Nemec
2026-11-08 17:49:39 +01:00
parent a343bde741
commit 8d18873412
82 changed files with 6401 additions and 34 deletions

View 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."
}
}
}
}
}