Skip to content

Commit adf1be9

Browse files
authored
Merge pull request #5544 from woocommerce/issue/5349-take-payment-ui
2 parents 16adfbd + 3fbccb9 commit adf1be9

File tree

5 files changed

+180
-1
lines changed

5 files changed

+180
-1
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import Foundation
2+
import SwiftUI
3+
4+
/// View to choose what payment method will be used with the simple payments order.
5+
///
6+
struct SimplePaymentsMethod: View {
7+
8+
/// Navigation bar title.
9+
///
10+
let title: String
11+
12+
var body: some View {
13+
VStack(alignment: .leading, spacing: Layout.noSpacing) {
14+
15+
Text(Localization.header)
16+
.subheadlineStyle()
17+
.padding()
18+
19+
Divider()
20+
21+
Group {
22+
MethodRow(icon: .priceImage, title: Localization.cash) {
23+
print("Tapped Cash")
24+
}
25+
26+
Divider()
27+
28+
MethodRow(icon: .creditCardImage, title: Localization.card) {
29+
print("Tapped Card")
30+
}
31+
}
32+
.padding(.horizontal)
33+
.background(Color(.listForeground))
34+
35+
Divider()
36+
37+
// Pushes content to the top
38+
Spacer()
39+
}
40+
.background(Color(.listBackground).ignoresSafeArea())
41+
.navigationTitle(title)
42+
}
43+
}
44+
45+
/// Represents a Payment method row
46+
///
47+
private struct MethodRow: View {
48+
/// Icon of the row
49+
///
50+
let icon: UIImage
51+
52+
/// Title of the row
53+
///
54+
let title: String
55+
56+
/// Action when the row is selected
57+
///
58+
let action: () -> ()
59+
60+
/// Keeps track of the current screen scale.
61+
///
62+
@ScaledMetric private var scale = 1
63+
64+
var body: some View {
65+
Button(action: action) {
66+
HStack {
67+
Image(uiImage: icon)
68+
.resizable()
69+
.flipsForRightToLeftLayoutDirection(true)
70+
.frame(width: SimplePaymentsMethod.Layout.iconWidthHeight(scale: scale),
71+
height: SimplePaymentsMethod.Layout.iconWidthHeight(scale: scale))
72+
.foregroundColor(Color(.systemGray))
73+
74+
Text(title)
75+
.bodyStyle()
76+
.frame(maxWidth: .infinity, alignment: .leading)
77+
78+
Image(uiImage: .chevronImage)
79+
.resizable()
80+
.flipsForRightToLeftLayoutDirection(true)
81+
.frame(width: SimplePaymentsMethod.Layout.chevronWidthHeight(scale: scale),
82+
height: SimplePaymentsMethod.Layout.chevronWidthHeight(scale: scale))
83+
.foregroundColor(Color(.systemGray))
84+
}
85+
.padding(.vertical, SimplePaymentsMethod.Layout.verticalPadding)
86+
}
87+
}
88+
}
89+
90+
// MARK: Constants
91+
private extension SimplePaymentsMethod {
92+
enum Localization {
93+
static let header = NSLocalizedString("Choose your payment method", comment: "Heading text on the select payment method screen for simple payments")
94+
static let cash = NSLocalizedString("Cash", comment: "Cash method title on the select payment method screen for simple payments")
95+
static let card = NSLocalizedString("Card", comment: "Card method title on the select payment method screen for simple payments")
96+
}
97+
98+
enum Layout {
99+
static let noSpacing: CGFloat = 0
100+
static let verticalPadding: CGFloat = 11
101+
102+
static func iconWidthHeight(scale: CGFloat) -> CGFloat {
103+
24 * scale
104+
}
105+
106+
static func chevronWidthHeight(scale: CGFloat) -> CGFloat {
107+
22 * scale
108+
}
109+
}
110+
}
111+
112+
// MARK: Previews
113+
struct SimplePaymentsMethod_Preview: PreviewProvider {
114+
static var previews: some View {
115+
NavigationView {
116+
SimplePaymentsMethod(title: "Take payment ($15.99)")
117+
.navigationBarTitleDisplayMode(.inline)
118+
}
119+
.environment(\.colorScheme, .light)
120+
.previewDisplayName("Light")
121+
122+
NavigationView {
123+
SimplePaymentsMethod(title: "Take payment ($15.99)")
124+
.navigationBarTitleDisplayMode(.inline)
125+
}
126+
.environment(\.colorScheme, .dark)
127+
.previewDisplayName("Dark")
128+
129+
NavigationView {
130+
SimplePaymentsMethod(title: "Take payment ($15.99)")
131+
.navigationBarTitleDisplayMode(.inline)
132+
}
133+
.environment(\.sizeCategory, .accessibilityExtraExtraLarge)
134+
.previewDisplayName("Accessibility")
135+
}
136+
}

WooCommerce/Classes/ViewRelated/Orders/Simple Payments/Summary/SimplePaymentsSummary.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ struct SimplePaymentsSummary: View {
3434
}
3535

3636
TakePaymentSection(viewModel: viewModel)
37+
38+
// Navigation To Payment Methods
39+
LazyNavigationLink(destination: SimplePaymentsMethod(title: Localization.takePayment(total: viewModel.total)),
40+
isActive: $viewModel.navigateToPaymentMethods) {
41+
EmptyView()
42+
}
3743
}
3844
.background(Color(.listBackground).ignoresSafeArea())
3945
.navigationTitle(Localization.title)

WooCommerce/Classes/ViewRelated/Orders/Simple Payments/Summary/SimplePaymentsSummaryViewModel.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ final class SimplePaymentsSummaryViewModel: ObservableObject {
2626
///
2727
@Published var enableTaxes: Bool = false
2828

29+
/// Defines when to navigate to the payments method screen.
30+
///
31+
@Published var navigateToPaymentMethods = false
32+
2933
/// Defines if a loading indicator should be shown.
3034
///
3135
@Published private(set) var showLoadingIndicator = false
@@ -152,7 +156,7 @@ final class SimplePaymentsSummaryViewModel: ObservableObject {
152156

153157
switch result {
154158
case .success:
155-
// TODO: Navigate to Payment Method
159+
self.navigateToPaymentMethods = true
156160
// TODO: Analytics
157161
break
158162
case .failure:

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@
391391
2611EE59243A473300A74490 /* ProductCategoryListViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2611EE58243A473300A74490 /* ProductCategoryListViewModelTests.swift */; };
392392
2614EB1C24EB611200968D4B /* TopBannerViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2614EB1B24EB611200968D4B /* TopBannerViewTests.swift */; };
393393
2619FA2C25C897930006DAFF /* AddAttributeOptionsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2619FA2B25C897930006DAFF /* AddAttributeOptionsViewModelTests.swift */; };
394+
261AA309275178FA009530FE /* SimplePaymentsMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 261AA308275178FA009530FE /* SimplePaymentsMethod.swift */; };
394395
262A09812628A8F40033AD20 /* WooStyleModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262A09802628A8F40033AD20 /* WooStyleModifiers.swift */; };
395396
262A098B2628C51D0033AD20 /* OrderAddOnListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262A098A2628C51D0033AD20 /* OrderAddOnListViewModel.swift */; };
396397
262A0999262908A60033AD20 /* OrderAddOnListI1Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 262A0998262908A60033AD20 /* OrderAddOnListI1Tests.swift */; };
@@ -1879,6 +1880,7 @@
18791880
2611EE58243A473300A74490 /* ProductCategoryListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductCategoryListViewModelTests.swift; sourceTree = "<group>"; };
18801881
2614EB1B24EB611200968D4B /* TopBannerViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBannerViewTests.swift; sourceTree = "<group>"; };
18811882
2619FA2B25C897930006DAFF /* AddAttributeOptionsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAttributeOptionsViewModelTests.swift; sourceTree = "<group>"; };
1883+
261AA308275178FA009530FE /* SimplePaymentsMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePaymentsMethod.swift; sourceTree = "<group>"; };
18821884
262A09802628A8F40033AD20 /* WooStyleModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooStyleModifiers.swift; sourceTree = "<group>"; };
18831885
262A098A2628C51D0033AD20 /* OrderAddOnListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderAddOnListViewModel.swift; sourceTree = "<group>"; };
18841886
262A0998262908A60033AD20 /* OrderAddOnListI1Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderAddOnListI1Tests.swift; sourceTree = "<group>"; };
@@ -3948,6 +3950,14 @@
39483950
path = "Variations/Add Attributes";
39493951
sourceTree = "<group>";
39503952
};
3953+
261AA30A27517907009530FE /* Method */ = {
3954+
isa = PBXGroup;
3955+
children = (
3956+
261AA308275178FA009530FE /* SimplePaymentsMethod.swift */,
3957+
);
3958+
path = Method;
3959+
sourceTree = "<group>";
3960+
};
39513961
262A097F2628A8BF0033AD20 /* View Modifiers */ = {
39523962
isa = PBXGroup;
39533963
children = (
@@ -4042,6 +4052,7 @@
40424052
26100B1D2721BAD800473045 /* SimplePaymentsTopBannerFactory.swift */,
40434053
26B9875A273C6A520090E8CA /* Amount */,
40444054
26B9875B273C6A670090E8CA /* Summary */,
4055+
261AA30A27517907009530FE /* Method */,
40454056
);
40464057
path = "Simple Payments";
40474058
sourceTree = "<group>";
@@ -7853,6 +7864,7 @@
78537864
02F6800325807C9B00C3BAD2 /* ShippingLabelPaperSizeOptionListView.swift in Sources */,
78547865
02E8B17723E2C49000A43403 /* InProgressProductImageCollectionViewCell.swift in Sources */,
78557866
CE5F462C23AACBC4006B1A5C /* RefundDetailsResultController.swift in Sources */,
7867+
261AA309275178FA009530FE /* SimplePaymentsMethod.swift in Sources */,
78567868
0230535B2374FB6800487A64 /* AztecSourceCodeFormatBarCommand.swift in Sources */,
78577869
D41C9F2E26D9A0E900993558 /* WhatsNewViewModel.swift in Sources */,
78587870
02ECD1E424FF5E0B00735BE5 /* AddProductCoordinator.swift in Sources */,

WooCommerce/WooCommerceTests/ViewRelated/Orders/Simple Payments/SimplePaymentsSummaryViewModelTests.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,25 @@ final class SimplePaymentsSummaryViewModelTests: XCTestCase {
142142
// Then
143143
XCTAssertTrue(receivedError)
144144
}
145+
146+
func test_when_order_is_updated_navigation_to_payments_method_is_triggered() {
147+
// Given
148+
let mockStores = MockStoresManager(sessionManager: .testingInstance)
149+
let viewModel = SimplePaymentsSummaryViewModel(providedAmount: "1.0", totalWithTaxes: "1.0", taxAmount: "0.0", stores: mockStores)
150+
mockStores.whenReceivingAction(ofType: OrderAction.self) { action in
151+
switch action {
152+
case let .updateSimplePaymentsOrder(_, _, _, _, _, _, _, onCompletion):
153+
onCompletion(.success(Order.fake()))
154+
default:
155+
XCTFail("Unexpected action: \(action)")
156+
}
157+
}
158+
XCTAssertFalse(viewModel.navigateToPaymentMethods)
159+
160+
// When
161+
viewModel.updateOrder()
162+
163+
// Then
164+
XCTAssertTrue(viewModel.navigateToPaymentMethods)
165+
}
145166
}

0 commit comments

Comments
 (0)