Skip to content

Commit adfdbf4

Browse files
authored
Merge pull request #5377 from woocommerce/issue/5344-summary-ui
2 parents f94dc0c + f1ac8e5 commit adfdbf4

File tree

3 files changed

+270
-9
lines changed

3 files changed

+270
-9
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import SwiftUI
2+
3+
/// View to summarize the Simple Payments order to be created
4+
///
5+
struct SimplePaymentsSummary: View {
6+
7+
/// Order note content
8+
///
9+
let noteContent: String?
10+
11+
var body: some View {
12+
VStack {
13+
ScrollView {
14+
VStack(spacing: Layout.noSpacing) {
15+
16+
CustomAmountSection()
17+
18+
Spacer(minLength: Layout.spacerHeight)
19+
20+
EmailSection()
21+
22+
Spacer(minLength: Layout.spacerHeight)
23+
24+
PaymentsSection()
25+
26+
Spacer(minLength: Layout.spacerHeight)
27+
28+
NoteSection(content: noteContent)
29+
}
30+
}
31+
32+
TakePaymentSection()
33+
}
34+
.background(Color(.listBackground))
35+
}
36+
}
37+
38+
/// Represents the Custom amount section
39+
///
40+
private struct CustomAmountSection: View {
41+
var body: some View {
42+
Group {
43+
Divider()
44+
45+
AdaptiveStack(horizontalAlignment: .leading, spacing: SimplePaymentsSummary.Layout.horizontalStackSpacing) {
46+
Image(uiImage: .priceImage)
47+
.padding()
48+
.foregroundColor(Color(.systemGray))
49+
.background(Color(.listBackground))
50+
51+
Text(SimplePaymentsSummary.Localization.customAmount)
52+
.headlineStyle()
53+
54+
// Temporary data
55+
Text("$40.00")
56+
.headlineStyle()
57+
.frame(maxWidth: .infinity, alignment: .trailing)
58+
}
59+
.bodyStyle()
60+
.padding()
61+
.background(Color(.listForeground))
62+
63+
Divider()
64+
}
65+
}
66+
}
67+
68+
/// Represents the email section
69+
///
70+
private struct EmailSection: View {
71+
var body: some View {
72+
Group {
73+
Divider()
74+
75+
TitleAndTextFieldRow(title: SimplePaymentsSummary.Localization.email,
76+
placeholder: SimplePaymentsSummary.Localization.emailPlaceHolder,
77+
text: .constant("")) // Temporary data
78+
.background(Color(.listForeground))
79+
80+
Divider()
81+
}
82+
}
83+
}
84+
85+
/// Represents the Payments Section
86+
///
87+
private struct PaymentsSection: View {
88+
var body: some View {
89+
Group {
90+
Divider()
91+
92+
VStack(alignment: .leading, spacing: SimplePaymentsSummary.Layout.verticalSummarySpacing) {
93+
94+
Text(SimplePaymentsSummary.Localization.payment)
95+
.headlineStyle()
96+
.padding([.horizontal, .top])
97+
98+
// Temporary data
99+
TitleAndValueRow(title: SimplePaymentsSummary.Localization.subtotal, value: .content("$40.0"), selectable: false) {}
100+
101+
// Temporary data
102+
TitleAndToggleRow(title: SimplePaymentsSummary.Localization.chargeTaxes, isOn: .constant(false))
103+
.padding([.leading, .trailing])
104+
105+
// Temporary data
106+
TitleAndValueRow(title: SimplePaymentsSummary.Localization.total, value: .content("$40.0"), bold: true, selectable: false) {}
107+
}
108+
.background(Color(.listForeground))
109+
110+
Divider()
111+
}
112+
}
113+
}
114+
115+
/// Represents the Order note section
116+
///
117+
private struct NoteSection: View {
118+
119+
/// Order note content
120+
///
121+
let content: String?
122+
123+
var body: some View {
124+
Group {
125+
Divider()
126+
127+
VStack(alignment: .leading, spacing: SimplePaymentsSummary.Layout.verticalNoteSpacing) {
128+
129+
HStack {
130+
Text(SimplePaymentsSummary.Localization.orderNote)
131+
.headlineStyle()
132+
.frame(maxWidth: .infinity, alignment: .leading)
133+
134+
Button(SimplePaymentsSummary.Localization.editNote) {
135+
print("Tapped on Edit")
136+
}
137+
.foregroundColor(Color(.accent))
138+
.bodyStyle()
139+
.renderedIf(content != nil)
140+
}
141+
142+
noteContent()
143+
144+
}
145+
.padding()
146+
.background(Color(.listForeground))
147+
148+
Divider()
149+
}
150+
}
151+
152+
/// Builds a button to add a note if no note is present. If there is a note present only displays it
153+
///
154+
@ViewBuilder private func noteContent() -> some View {
155+
if let content = content {
156+
157+
Text(content)
158+
.bodyStyle()
159+
160+
} else {
161+
162+
Button(action: {
163+
print("Tapped add note")
164+
}, label: {
165+
HStack() {
166+
Image(uiImage: .plusImage)
167+
168+
Text(SimplePaymentsSummary.Localization.addNote)
169+
.frame(maxWidth: .infinity, alignment: .leading)
170+
}
171+
.foregroundColor(Color(.accent))
172+
.bodyStyle()
173+
})
174+
.frame(maxWidth: .infinity)
175+
}
176+
}
177+
}
178+
179+
/// Represents the bottom take payment button
180+
///
181+
private struct TakePaymentSection: View {
182+
var body: some View {
183+
VStack {
184+
Divider()
185+
186+
// Temporary data
187+
Button(SimplePaymentsSummary.Localization.takePayment(total: "$40.0"), action: {
188+
print("Take payment pressed")
189+
})
190+
.buttonStyle(PrimaryButtonStyle())
191+
.padding()
192+
193+
}
194+
.background(Color(.listForeground))
195+
}
196+
}
197+
198+
// MARK: Constants
199+
private extension SimplePaymentsSummary {
200+
enum Layout {
201+
static let spacerHeight: CGFloat = 16.0
202+
static let horizontalStackSpacing: CGFloat = 16.0
203+
static let verticalSummarySpacing: CGFloat = 8.0
204+
static let verticalNoteSpacing: CGFloat = 22.0
205+
static let noSpacing: CGFloat = 0.0
206+
}
207+
208+
enum Localization {
209+
static let customAmount = NSLocalizedString("Custom Amount",
210+
comment: "Title text of the row that shows the provided amount when creating a simple payment")
211+
static let email = NSLocalizedString("Email",
212+
comment: "Title text of the row that holds the provided email when creating a simple payment")
213+
static let emailPlaceHolder = NSLocalizedString("Enter Email",
214+
comment: "Placeholder of the row that holds the provided email when creating a simple payment")
215+
static let payment = NSLocalizedString("Payment",
216+
comment: "Title text of the row that shows the payment headline when creating a simple payment")
217+
static let subtotal = NSLocalizedString("Subtotal",
218+
comment: "Title text of the row that shows the subtotal when creating a simple payment")
219+
static let chargeTaxes = NSLocalizedString("Charge Taxes",
220+
comment: "Title text of the row that has a switch when creating a simple payment")
221+
static let total = NSLocalizedString("Order Total",
222+
comment: "Title text of the row that shows the total to charge when creating a simple payment")
223+
static let orderNote = NSLocalizedString("Order Note",
224+
comment: "Title text of the row that holds the order note when creating a simple payment")
225+
static let addNote = NSLocalizedString("Add Note",
226+
comment: "Title text of the button that adds a note when creating a simple payment")
227+
static let editNote = NSLocalizedString("Edit",
228+
comment: "Title text of the button that edits a note when creating a simple payment")
229+
230+
static func takePayment(total: String) -> String {
231+
NSLocalizedString("Take Payment (\(total))",
232+
comment: "Text of the button that creates a simple payment order. Contains the total amount to collect")
233+
}
234+
}
235+
}
236+
237+
// MARK: Previews
238+
struct SimplePaymentsSummary_Preview: PreviewProvider {
239+
static var previews: some View {
240+
SimplePaymentsSummary(noteContent: nil)
241+
.environment(\.colorScheme, .light)
242+
.previewDisplayName("Light")
243+
244+
SimplePaymentsSummary(noteContent: "Dispatch by tomorrow morning at Fake Street 123, via the boulevard.")
245+
.environment(\.colorScheme, .light)
246+
.previewDisplayName("Light Content")
247+
248+
SimplePaymentsSummary(noteContent: nil)
249+
.environment(\.colorScheme, .dark)
250+
.previewDisplayName("Dark")
251+
252+
SimplePaymentsSummary(noteContent: nil)
253+
.environment(\.sizeCategory, .accessibilityExtraExtraLarge)
254+
.previewDisplayName("Accessibility")
255+
}
256+
}

WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/TitleAndValueRow.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,20 @@ struct TitleAndValueRow: View {
66

77
let title: String
88
let value: Value
9+
var bold: Bool = false
910
let selectable: Bool
1011
var action: () -> Void
1112

1213
var body: some View {
1314
Button(action: {
14-
guard selectable else {
15-
return
16-
}
1715
action()
1816
}, label: {
1917
HStack {
2018
AdaptiveStack(horizontalAlignment: .leading) {
2119
Text(title)
22-
.bodyStyle()
20+
.style(bold: bold)
2321
Text(value.text)
24-
.style(for: value)
22+
.style(for: value, bold: bold)
2523
.frame(maxWidth: .infinity, alignment: .trailing)
2624
.padding(.vertical, Constants.verticalPadding)
2725
}
@@ -34,6 +32,7 @@ struct TitleAndValueRow: View {
3432
}
3533
.contentShape(Rectangle())
3634
})
35+
.disabled(!selectable)
3736
.frame(minHeight: Constants.minHeight)
3837
.padding(.horizontal, Constants.horizontalPadding)
3938
}
@@ -69,11 +68,13 @@ extension TitleAndValueRow {
6968
private extension Text {
7069
/// Styles the text based on the type of content.
7170
///
72-
@ViewBuilder func style(for value: TitleAndValueRow.Value) -> some View {
73-
switch value {
74-
case .placeholder:
71+
@ViewBuilder func style(for value: TitleAndValueRow.Value = .content(""), bold: Bool) -> some View {
72+
switch (value, bold) {
73+
case (.placeholder, _):
7574
self.modifier(SecondaryBodyStyle())
76-
case .content:
75+
case (.content, true):
76+
self.modifier(HeadlineStyle())
77+
case (.content, false):
7778
self.modifier(BodyStyle(isEnabled: true))
7879
}
7980
}

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@
455455
26C6E8EC26E8FF4800C7BB0F /* LazyNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C6E8EB26E8FF4800C7BB0F /* LazyNavigationLink.swift */; };
456456
26CCBE0B2523B3650073F94D /* RefundProductsTotalTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26CCBE0A2523B3650073F94D /* RefundProductsTotalTableViewCell.swift */; };
457457
26CCBE0D2523C2560073F94D /* RefundProductsTotalTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 26CCBE0C2523C2560073F94D /* RefundProductsTotalTableViewCell.xib */; };
458+
26CFDB2727357E8000AB940B /* SimplePaymentsSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26CFDB2627357E8000AB940B /* SimplePaymentsSummary.swift */; };
458459
26E0ADF12631D94D00A5EB3B /* TopBannerWrapperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0ADF02631D94D00A5EB3B /* TopBannerWrapperView.swift */; };
459460
26E0AE13263359F900A5EB3B /* View+Conditionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0AE12263359F900A5EB3B /* View+Conditionals.swift */; };
460461
26E0AE1926335AA900A5EB3B /* Survey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0AE1826335AA900A5EB3B /* Survey.swift */; };
@@ -1914,6 +1915,7 @@
19141915
26C6E8EB26E8FF4800C7BB0F /* LazyNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyNavigationLink.swift; sourceTree = "<group>"; };
19151916
26CCBE0A2523B3650073F94D /* RefundProductsTotalTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundProductsTotalTableViewCell.swift; sourceTree = "<group>"; };
19161917
26CCBE0C2523C2560073F94D /* RefundProductsTotalTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RefundProductsTotalTableViewCell.xib; sourceTree = "<group>"; };
1918+
26CFDB2627357E8000AB940B /* SimplePaymentsSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePaymentsSummary.swift; sourceTree = "<group>"; };
19171919
26E0ADF02631D94D00A5EB3B /* TopBannerWrapperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBannerWrapperView.swift; sourceTree = "<group>"; };
19181920
26E0AE12263359F900A5EB3B /* View+Conditionals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Conditionals.swift"; sourceTree = "<group>"; };
19191921
26E0AE1826335AA900A5EB3B /* Survey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Survey.swift; sourceTree = "<group>"; };
@@ -3981,6 +3983,7 @@
39813983
2678897B270E6E8B00BD249E /* SimplePaymentsAmount.swift */,
39823984
262AF386271114CC00E39AFF /* SimplePaymentsAmountViewModel.swift */,
39833985
26100B1D2721BAD800473045 /* SimplePaymentsTopBannerFactory.swift */,
3986+
26CFDB2627357E8000AB940B /* SimplePaymentsSummary.swift */,
39843987
);
39853988
path = "Simple Payments";
39863989
sourceTree = "<group>";
@@ -8126,6 +8129,7 @@
81268129
26CCBE0B2523B3650073F94D /* RefundProductsTotalTableViewCell.swift in Sources */,
81278130
0229ED00258767BC00C336F8 /* ShippingLabelPrintingStepContentView.swift in Sources */,
81288131
D8EE9698264D3CCB0033B2F9 /* ReceiptViewModel.swift in Sources */,
8132+
26CFDB2727357E8000AB940B /* SimplePaymentsSummary.swift in Sources */,
81298133
CE1CCB4B20570B1F000EE3AC /* OrderTableViewCell.swift in Sources */,
81308134
748AD087219F481B00023535 /* UIView+Animation.swift in Sources */,
81318135
02564A8A246CDF6100D6DB2A /* ProductsTopBannerFactory.swift in Sources */,

0 commit comments

Comments
 (0)