@@ -7,51 +7,106 @@ struct OrderDetailsShippingAddressMapView: View {
77
88 var body : some View {
99 VStack ( spacing: 0 ) {
10- if viewModel. isValidAddress {
11- Group {
12- if let coordinate = viewModel. coordinate {
13- Map ( position: . constant( viewModel. cameraPosition) ) {
14- Annotation ( viewModel. shippingAddress? . fullNameWithCompany ?? " Address " , coordinate: coordinate) {
15- Image ( systemName: " mappin.circle.fill " )
16- . foregroundColor ( . red)
17- . font ( . title)
18- . background ( Color . white. clipShape ( Circle ( ) ) )
19- }
20- }
21- . mapStyle ( . standard)
22- . mapControlVisibility ( . hidden)
23- . disabled ( true ) // Disable user interaction (scrolling, zooming)
24- . frame ( height: viewModel. mapHeight)
25- . clipShape ( RoundedRectangle ( cornerRadius: 8 ) )
26- . contentShape ( Rectangle ( ) )
27- . onTapGesture {
28- viewModel. onMapTapped ? ( )
29- }
30- } else if viewModel. isGeocoding {
31- RoundedRectangle ( cornerRadius: 8 )
32- . fill ( Color . gray. opacity ( 0.3 ) )
33- . frame ( height: viewModel. mapHeight)
34- . overlay (
35- ProgressView ( )
36- . progressViewStyle ( CircularProgressViewStyle ( ) )
37- )
38- } else {
39- // Empty state or failed geocoding
40- RoundedRectangle ( cornerRadius: 8 )
41- . fill ( Color . gray. opacity ( 0.2 ) )
42- . frame ( height: viewModel. mapHeight)
43- . overlay (
44- Image ( systemName: " map " )
45- . foregroundColor ( . gray)
46- . font ( . title2)
47- )
48- . contentShape ( Rectangle ( ) )
49- . onTapGesture {
50- viewModel. onMapTapped ? ( )
51- }
10+ switch viewModel. mapState {
11+ case let . loaded( coordinate, cameraPosition) :
12+ Map ( position: . constant( cameraPosition) ) {
13+ Annotation ( " " , coordinate: coordinate) {
14+ Image ( systemName: " mappin.circle.fill " )
15+ . foregroundColor ( . red)
16+ . font ( . title)
17+ . background ( Color . white. clipShape ( Circle ( ) ) )
5218 }
5319 }
20+ . mapStyle ( . standard)
21+ . mapControlVisibility ( . hidden)
22+ . disabled ( true ) // Disable user interaction (scrolling, zooming)
23+ . clipShape ( RoundedRectangle ( cornerRadius: Layout . cornerRadius) )
24+ . contentShape ( Rectangle ( ) )
25+ . onTapGesture {
26+ viewModel. onMapTapped ? ( )
27+ }
28+ case . loading:
29+ RoundedRectangle ( cornerRadius: Layout . cornerRadius)
30+ . fill ( Color . gray. opacity ( 0.3 ) )
31+ . overlay (
32+ ProgressView ( )
33+ . progressViewStyle ( CircularProgressViewStyle ( ) )
34+ )
35+ case . failed, . none:
36+ RoundedRectangle ( cornerRadius: Layout . cornerRadius)
37+ . fill ( Color . gray. opacity ( 0.2 ) )
38+ . overlay (
39+ Image ( systemName: " map " )
40+ . foregroundColor ( . gray)
41+ . font ( . title2)
42+ )
43+ . contentShape ( Rectangle ( ) )
44+ . onTapGesture {
45+ viewModel. onMapTapped ? ( )
46+ }
5447 }
5548 }
49+ . frame ( height: viewModel. mapHeight)
50+ . renderedIf ( viewModel. isValidAddress)
5651 }
5752}
53+
54+ @available ( iOS 17 . 0 , * )
55+ private extension OrderDetailsShippingAddressMapView {
56+ enum Layout {
57+ static let cornerRadius : CGFloat = 8
58+ }
59+ }
60+
61+ #if DEBUG
62+
63+ import struct Yosemite. Address
64+
65+ @available ( iOS 17 . 0 , * )
66+ #Preview {
67+ let sampleAddress = Address (
68+ firstName: " " ,
69+ lastName: " " ,
70+ company: " " ,
71+ address1: " 60 29th Street #343 " ,
72+ address2: " Suite 100 " ,
73+ city: " San Francisco " ,
74+ state: " CA " ,
75+ postcode: " 94102 " ,
76+ country: " US " ,
77+ phone: " +1-555-0123 " ,
78+ 79+ )
80+ let viewModel = OrderDetailsShippingAddressMapViewModel ( shippingAddress: sampleAddress)
81+ return OrderDetailsShippingAddressMapView( viewModel: viewModel)
82+ . padding ( )
83+ }
84+
85+ @available ( iOS 17 . 0 , * )
86+ #Preview( " Invalid address " ) {
87+ let sampleAddress = Address (
88+ firstName: " " ,
89+ lastName: " " ,
90+ company: " " ,
91+ address1: " " ,
92+ address2: " " ,
93+ city: " ZZ " ,
94+ state: " " ,
95+ postcode: " " ,
96+ country: " US " ,
97+ phone: " +1-555-0123 " ,
98+ 99+ )
100+ let viewModel = OrderDetailsShippingAddressMapViewModel ( shippingAddress: sampleAddress)
101+ return OrderDetailsShippingAddressMapView ( viewModel: viewModel)
102+ . padding ( )
103+ }
104+
105+ @available ( iOS 17 . 0 , * )
106+ #Preview( " No address " ) {
107+ let viewModel = OrderDetailsShippingAddressMapViewModel ( shippingAddress: nil )
108+ return OrderDetailsShippingAddressMapView ( viewModel: viewModel)
109+ . padding ( )
110+ }
111+
112+ #endif
0 commit comments