Skip to content

Commit 2576e3f

Browse files
authored
Merge pull request #5864 from woocommerce/issue/5412-update-customer-section
Order Creation: Update customer section
2 parents 49c4bb1 + d0369b1 commit 2576e3f

File tree

7 files changed

+192
-86
lines changed

7 files changed

+192
-86
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/OrderCustomerSection.swift

Lines changed: 77 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,101 +3,110 @@ import SwiftUI
33
/// Represents the Customer section
44
///
55
struct OrderCustomerSection: View {
6-
let geometry: GeometryProxy
76

8-
/// View model to drive the view content
9-
let viewModel: NewOrderViewModel.CustomerDataViewModel
7+
/// Parent view model to access all data
8+
@ObservedObject var viewModel: NewOrderViewModel
109

11-
/// View model for Address Form
12-
let addressFormViewModel: CreateOrderAddressFormViewModel
10+
/// View model to drive the view content
11+
private var customerDataViewModel: NewOrderViewModel.CustomerDataViewModel {
12+
viewModel.customerDataViewModel
13+
}
1314

1415
@State private var showAddressForm: Bool = false
1516

1617
var body: some View {
17-
Group {
18-
Divider()
18+
OrderCustomerSectionContent(viewModel: viewModel.customerDataViewModel, showAddressForm: $showAddressForm)
19+
.sheet(isPresented: $showAddressForm) {
20+
NavigationView {
21+
EditOrderAddressForm(dismiss: {
22+
showAddressForm.toggle()
23+
}, viewModel: viewModel.createOrderAddressFormViewModel())
24+
}
25+
}
26+
}
27+
}
1928

20-
VStack(alignment: .leading) {
21-
HStack(alignment: .top) {
22-
Text(Localization.customer)
23-
.headlineStyle()
24-
25-
Spacer()
26-
27-
if viewModel.isDataAvailable {
28-
Button(Localization.editButton) {
29-
showAddressForm.toggle()
30-
}
31-
.buttonStyle(LinkButtonStyle())
32-
.fixedSize(horizontal: true, vertical: true)
33-
.padding(.top, -Layout.linkButtonTopPadding) // remove padding to align button title to the top
34-
.padding(.trailing, -Layout.linkButtonTrailingPadding) // remove padding to align button title to the side
35-
}
36-
}
29+
private struct OrderCustomerSectionContent: View {
30+
31+
/// View model to drive the view content
32+
var viewModel: NewOrderViewModel.CustomerDataViewModel
33+
34+
@Binding var showAddressForm: Bool
35+
36+
@Environment(\.safeAreaInsets) var safeAreaInsets: EdgeInsets
37+
38+
var body: some View {
39+
Divider()
3740

38-
if !viewModel.isDataAvailable {
39-
createCustomerView
40-
} else {
41-
customerDataView
41+
VStack(alignment: .leading, spacing: .zero) {
42+
HStack(alignment: .top) {
43+
Text(Localization.customer)
44+
.headlineStyle()
45+
46+
Spacer()
47+
48+
if viewModel.isDataAvailable {
49+
Button(Localization.editButton) {
50+
showAddressForm.toggle()
51+
}
52+
.buttonStyle(LinkButtonStyle())
53+
.fixedSize(horizontal: true, vertical: true)
54+
.padding(.top, -Layout.linkButtonTopPadding) // remove padding to align button title to the top
55+
.padding(.trailing, -Layout.linkButtonTrailingPadding) // remove padding to align button title to the side
4256
}
4357
}
44-
.padding(.horizontal, insets: geometry.safeAreaInsets)
45-
.padding()
46-
.background(Color(.listForeground))
58+
.padding([.leading, .top, .trailing])
4759

48-
Divider()
49-
}
50-
.sheet(isPresented: $showAddressForm) {
51-
NavigationView {
52-
EditOrderAddressForm(dismiss: {
53-
showAddressForm.toggle()
54-
}, viewModel: addressFormViewModel)
60+
if !viewModel.isDataAvailable {
61+
Spacer(minLength: Layout.verticalHeadlineSpacing)
62+
createCustomerView
63+
} else {
64+
customerDataView
5565
}
5666
}
67+
.padding(.horizontal, insets: safeAreaInsets)
68+
.background(Color(.listForeground))
69+
70+
Divider()
5771
}
5872

5973
private var createCustomerView: some View {
6074
Button(Localization.addCustomer) {
6175
showAddressForm.toggle()
6276
}
6377
.buttonStyle(PlusButtonStyle())
78+
.padding([.leading, .bottom, .trailing])
6479
}
6580

6681
private var customerDataView: some View {
6782
Group {
68-
VStack(alignment: .leading, spacing: Layout.verticalEmailSpacing) {
69-
if let fullName = viewModel.fullName {
70-
Text(fullName)
71-
.bodyStyle()
72-
}
73-
if let email = viewModel.email {
74-
Text(email)
75-
.footnoteStyle()
76-
}
77-
}
78-
if let billingAddressFormatted = viewModel.billingAddressFormatted {
79-
addressDetails(title: Localization.billingTitle, formattedAddress: billingAddressFormatted)
80-
}
81-
if let shippingAddressFormatted = viewModel.shippingAddressFormatted {
82-
addressDetails(title: Localization.shippingTitle, formattedAddress: shippingAddressFormatted)
83-
}
83+
addressDetails(title: Localization.shippingTitle, formattedAddress: viewModel.shippingAddressFormatted)
84+
Divider()
85+
.padding(.leading)
86+
addressDetails(title: Localization.billingTitle, formattedAddress: viewModel.billingAddressFormatted)
8487
}
8588
}
8689

87-
@ViewBuilder private func addressDetails(title: String, formattedAddress: String) -> some View {
88-
Divider()
90+
@ViewBuilder private func addressDetails(title: String, formattedAddress: String?) -> some View {
8991
VStack(alignment: .leading, spacing: Layout.verticalAddressSpacing) {
9092
Text(title)
9193
.headlineStyle()
92-
Text(formattedAddress)
93-
.bodyStyle()
94+
if let formattedAddress = formattedAddress, formattedAddress.isNotEmpty {
95+
Text(formattedAddress)
96+
.bodyStyle()
97+
} else {
98+
Text(Localization.noAddress)
99+
.bodyStyle()
100+
}
94101
}
102+
.padding()
95103
}
96104
}
97105

98106
// MARK: Constants
99-
private extension OrderCustomerSection {
107+
private extension OrderCustomerSectionContent {
100108
enum Layout {
109+
static let verticalHeadlineSpacing: CGFloat = 22.0
101110
static let verticalEmailSpacing: CGFloat = 4.0
102111
static let verticalAddressSpacing: CGFloat = 6.0
103112
static let linkButtonTopPadding: CGFloat = 12.0
@@ -111,28 +120,28 @@ private extension OrderCustomerSection {
111120

112121
static let billingTitle = NSLocalizedString("Billing Address", comment: "Title for the Billing Address section in order customer data")
113122
static let shippingTitle = NSLocalizedString("Shipping Address", comment: "Title for the Edit Shipping Address section in order customer data")
123+
124+
static let noAddress = NSLocalizedString("No address specified.", comment: "Placeholder for empty address in order customer data")
114125
}
115126
}
116127

128+
@available(iOS 15.0, *)
117129
struct OrderCustomerSection_Previews: PreviewProvider {
118130
static var previews: some View {
119-
let orderAdressFormViewModel = NewOrderViewModel(siteID: 123).createOrderAddressFormViewModel()
120131
let emptyViewModel = NewOrderViewModel.CustomerDataViewModel(billingAddress: nil, shippingAddress: nil)
121132
let addressViewModel = NewOrderViewModel.CustomerDataViewModel(fullName: "Johnny Appleseed",
122133
123-
billingAddressFormatted: """
134+
billingAddressFormatted: nil,
135+
shippingAddressFormatted: """
124136
Johnny Appleseed
125137
234 70th Street
126138
Niagara Falls NY 14304
127139
US
128-
""",
129-
shippingAddressFormatted: nil)
140+
""")
130141

131-
GeometryReader { geometry in
132-
ScrollView {
133-
OrderCustomerSection(geometry: geometry, viewModel: emptyViewModel, addressFormViewModel: orderAdressFormViewModel)
134-
OrderCustomerSection(geometry: geometry, viewModel: addressViewModel, addressFormViewModel: orderAdressFormViewModel)
135-
}
142+
ScrollView {
143+
OrderCustomerSectionContent(viewModel: emptyViewModel, showAddressForm: .constant(false))
144+
OrderCustomerSectionContent(viewModel: addressViewModel, showAddressForm: .constant(false))
136145
}
137146
}
138147
}

WooCommerce/Classes/ViewRelated/Orders/Order Creation/NewOrder.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct NewOrder: View {
5252
ScrollViewReader { scroll in
5353
ScrollView {
5454
VStack(spacing: Layout.noSpacing) {
55-
OrderStatusSection(geometry: geometry, viewModel: viewModel)
55+
OrderStatusSection(viewModel: viewModel)
5656

5757
Spacer(minLength: Layout.sectionSpacing)
5858

@@ -66,9 +66,7 @@ struct NewOrder: View {
6666
Spacer(minLength: Layout.sectionSpacing)
6767
}
6868

69-
OrderCustomerSection(geometry: geometry,
70-
viewModel: viewModel.customerDataViewModel,
71-
addressFormViewModel: viewModel.createOrderAddressFormViewModel())
69+
OrderCustomerSection(viewModel: viewModel)
7270
}
7371
}
7472
.background(Color(.listBackground).ignoresSafeArea())

WooCommerce/Classes/ViewRelated/Orders/Order Creation/NewOrderViewModel.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,6 @@ final class NewOrderViewModel: ObservableObject {
4646
///
4747
@Published var shouldShowOrderStatusList: Bool = false
4848

49-
/// Representation of customer data display properties.
50-
///
51-
@Published private(set) var customerDataViewModel: CustomerDataViewModel = .init(billingAddress: nil, shippingAddress: nil)
52-
53-
/// Assign this closure to be notified when a new order is created
54-
///
55-
var onOrderCreated: (Order) -> Void = { _ in }
56-
5749
/// Status Results Controller.
5850
///
5951
private lazy var statusResultsController: ResultsController<StorageOrderStatus> = {
@@ -139,6 +131,12 @@ final class NewOrderViewModel: ObservableObject {
139131
configureProductRowViewModels()
140132
}
141133

134+
// MARK: Customer data properties
135+
136+
/// Representation of customer data display properties.
137+
///
138+
@Published private(set) var customerDataViewModel: CustomerDataViewModel = .init(billingAddress: nil, shippingAddress: nil)
139+
142140
/// Creates a view model to be used in Address Form for customer address.
143141
///
144142
func createOrderAddressFormViewModel() -> CreateOrderAddressFormViewModel {
@@ -170,6 +168,10 @@ final class NewOrderViewModel: ObservableObject {
170168
}
171169
stores.dispatch(action)
172170
}
171+
172+
/// Assign this closure to be notified when a new order is created
173+
///
174+
var onOrderCreated: (Order) -> Void = { _ in }
173175
}
174176

175177
// MARK: - Types

WooCommerce/Classes/ViewRelated/Orders/Order Creation/StatusSection/OrderStatusSection.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import Yosemite
44
/// Represents the Status section with date label, status badge and edit button.
55
///
66
struct OrderStatusSection: View {
7-
let geometry: GeometryProxy
87
@ObservedObject var viewModel: NewOrderViewModel
98

9+
@Environment(\.safeAreaInsets) var safeAreaInsets: EdgeInsets
10+
1011
var body: some View {
1112
Divider()
1213

@@ -38,7 +39,7 @@ struct OrderStatusSection: View {
3839
}
3940
}
4041
}
41-
.padding(.horizontal, insets: geometry.safeAreaInsets)
42+
.padding(.horizontal, insets: safeAreaInsets)
4243
.padding([.leading, .trailing, .top])
4344
.background(Color(.listForeground))
4445

@@ -66,10 +67,8 @@ struct OrderStatusSection_Previews: PreviewProvider {
6667
static var previews: some View {
6768
let viewModel = NewOrderViewModel(siteID: 123)
6869

69-
GeometryReader { geometry in
70-
ScrollView {
71-
OrderStatusSection(geometry: geometry, viewModel: viewModel)
72-
}
70+
ScrollView {
71+
OrderStatusSection(viewModel: viewModel)
7372
}
7473
}
7574
}

WooCommerce/Classes/ViewRelated/Orders/Order Details/Address Edit/EditOrderAddressForm.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct EditOrderAddressForm<ViewModel: AddressFormViewModelProtocol>: View {
146146
text: $viewModel.fields.email,
147147
symbol: nil,
148148
keyboardType: .emailAddress)
149+
.autocapitalization(.none)
149150
.renderedIf(viewModel.showEmailField)
150151
Divider()
151152
.padding(.leading, Constants.dividerPadding)
@@ -222,6 +223,7 @@ struct EditOrderAddressForm<ViewModel: AddressFormViewModelProtocol>: View {
222223
.background(Color(.systemBackground))
223224
}
224225
}
226+
.disableAutocorrection(true)
225227
.background(Color(.listBackground))
226228
.ignoresSafeArea(.container, edges: [.horizontal, .bottom])
227229

0 commit comments

Comments
 (0)