Skip to content

Commit 6675046

Browse files
authored
Merge pull request #6572 from woocommerce/issue/6488-start-filling-data-in-editing-coupon
Improvements to the Edit Coupon view UI
2 parents a54d825 + fcd7de4 commit 6675046

File tree

4 files changed

+116
-54
lines changed

4 files changed

+116
-54
lines changed

WooCommerce/Classes/Model/Coupon+Woo.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension Coupon.DiscountType {
2424
case .percent:
2525
return Localization.titleCreatePercentageDiscount
2626
case .fixedCart:
27-
return Localization.titleCreateFixedCardDiscount
27+
return Localization.titleCreateFixedCartDiscount
2828
case .fixedProduct:
2929
return Localization.titleCreateFixedProductDiscount
3030
default:
@@ -39,7 +39,7 @@ extension Coupon.DiscountType {
3939
case .percent:
4040
return Localization.titleEditPercentageDiscount
4141
case .fixedCart:
42-
return Localization.titleEditFixedCardDiscount
42+
return Localization.titleEditFixedCartDiscount
4343
case .fixedProduct:
4444
return Localization.titleEditFixedProductDiscount
4545
default:
@@ -55,9 +55,9 @@ extension Coupon.DiscountType {
5555
static let titleEditPercentageDiscount = NSLocalizedString(
5656
"Edit percentage discount",
5757
comment: "Title of the view for editing a coupon with percentage discount.")
58-
static let titleEditFixedCardDiscount = NSLocalizedString(
59-
"Edit fixed card discount",
60-
comment: "Title of the view for editing a coupon with fixed card discount.")
58+
static let titleEditFixedCartDiscount = NSLocalizedString(
59+
"Edit fixed cart discount",
60+
comment: "Title of the view for editing a coupon with fixed cart discount.")
6161
static let titleEditFixedProductDiscount = NSLocalizedString(
6262
"Edit fixed product discount",
6363
comment: "Title of the view for editing a coupon with fixed product discount.")
@@ -67,9 +67,9 @@ extension Coupon.DiscountType {
6767
static let titleCreatePercentageDiscount = NSLocalizedString(
6868
"Create percentage discount",
6969
comment: "Title of the view for creating a coupon with percentage discount.")
70-
static let titleCreateFixedCardDiscount = NSLocalizedString(
71-
"Create fixed card discount",
72-
comment: "Title of the view for creating a coupon with fixed card discount.")
70+
static let titleCreateFixedCartDiscount = NSLocalizedString(
71+
"Create fixed cart discount",
72+
comment: "Title of the view for creating a coupon with fixed cart discount.")
7373
static let titleCreateFixedProductDiscount = NSLocalizedString(
7474
"Create fixed product discount",
7575
comment: "Title of the view for creating a coupon with fixed product discount.")

WooCommerce/Classes/ViewRelated/Coupons/Add and Edit Coupons/AddEditCoupon.swift

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,61 @@ struct AddEditCoupon: View {
1717
NavigationView {
1818
GeometryReader { geometry in
1919
ScrollView {
20-
VStack (alignment: .leading) {
20+
VStack (alignment: .leading, spacing: 0) {
2121
Group {
2222
ListHeaderView(text: Localization.headerCouponDetails.uppercased(), alignment: .left)
2323

2424
Group {
25-
TitleAndTextFieldRow(title: Localization.couponAmountPercentage,
26-
placeholder: Localization.couponAmountPercentage,
25+
TitleAndTextFieldRow(title: viewModel.amountLabel,
26+
placeholder: "0",
2727
text: $viewModel.amountField,
28-
editable: false,
28+
editable: true,
2929
fieldAlignment: .leading,
30-
keyboardType: .asciiCapableNumberPad)
30+
keyboardType: .decimalPad)
3131
Divider()
3232
.padding(.leading, Constants.margin)
33-
}
3433

35-
Text(Localization.footerCouponAmountPercentage)
36-
.subheadlineStyle()
37-
.padding(.horizontal, Constants.margin)
34+
Text(viewModel.amountSubtitleLabel)
35+
.subheadlineStyle()
36+
.padding(.horizontal, Constants.margin)
37+
}
38+
.padding(.bottom, Constants.verticalSpacing)
3839

3940
Group {
4041
TitleAndTextFieldRow(title: Localization.couponCode,
41-
placeholder: Localization.couponCode,
42+
placeholder: Localization.couponCodePlaceholder,
4243
text: $viewModel.codeField,
43-
editable: false,
44+
editable: true,
4445
fieldAlignment: .leading,
45-
keyboardType: .asciiCapableNumberPad)
46+
keyboardType: .default)
4647
Divider()
4748
.padding(.leading, Constants.margin)
49+
.padding(.bottom, Constants.verticalSpacing)
50+
Text(Localization.footerCouponCode)
51+
.subheadlineStyle()
52+
.padding(.horizontal, Constants.margin)
4853
}
54+
.padding(.bottom, Constants.verticalSpacing)
4955

50-
Text(Localization.footerCouponCode)
51-
.subheadlineStyle()
52-
.padding(.horizontal, Constants.margin)
53-
54-
//TODO: leading aligning for this button
5556
Button {
5657
//TODO: handle action
5758
} label: {
5859
Text(Localization.regenerateCouponCodeButton)
5960
}
6061
.buttonStyle(LinkButtonStyle())
61-
.padding(.horizontal, Constants.margin)
62+
.fixedSize()
63+
.frame(maxWidth: .infinity, alignment: .leading)
64+
.padding(.bottom, Constants.verticalSpacing)
6265

6366
Button {
6467
//TODO: handle action
6568
} label: {
66-
Text(Localization.addDescriptionButton)
67-
.bodyStyle()
69+
HStack {
70+
Image(uiImage: .plusImage)
71+
.frame(width: Constants.iconSize, height: Constants.iconSize)
72+
Text(Localization.addDescriptionButton)
73+
.bodyStyle()
74+
}
6875
}
6976
.buttonStyle(SecondaryButtonStyle())
7077
.padding(.horizontal, Constants.margin)
@@ -77,38 +84,50 @@ struct AddEditCoupon: View {
7784
Divider()
7885
.padding(.leading, Constants.margin)
7986
}
87+
.padding(.bottom, Constants.verticalSpacing)
8088

8189
Group {
8290
TitleAndToggleRow(title: Localization.includeFreeShipping, isOn: .constant(false))
8391
.padding(.horizontal, Constants.margin)
8492
Divider()
8593
.padding(.leading, Constants.margin)
8694
}
95+
.padding(.bottom, Constants.verticalSpacing)
8796
}
8897

8998
Group {
9099
ListHeaderView(text: Localization.headerApplyCouponTo.uppercased(), alignment: .left)
100+
.padding(.bottom, Constants.verticalSpacing)
91101

92-
// TODO: add a new style with the icon on the left side
93102
Button {
94103
//TODO: handle action
95104
} label: {
96-
Text(Localization.editProductsButton)
97-
.bodyStyle()
105+
HStack {
106+
Image(uiImage: .pencilImage).colorMultiply(Color(.text))
107+
.frame(width: Constants.iconSize, height: Constants.iconSize)
108+
Text(Localization.editProductsButton)
109+
.bodyStyle()
110+
}
98111
}
99112
.buttonStyle(SecondaryButtonStyle())
100113
.padding(.horizontal, Constants.margin)
114+
.padding(.bottom, Constants.verticalSpacing)
101115

102-
// TODO: add a new style with the icon on the left side
103116
Button {
104117
//TODO: handle action
105118
} label: {
106-
Text(Localization.editProductCategoriesButton)
107-
.bodyStyle()
119+
HStack {
120+
Image(uiImage: .pencilImage)
121+
.colorMultiply(Color(.text))
122+
.frame(width: Constants.iconSize, height: Constants.iconSize)
123+
Text(Localization.editProductCategoriesButton)
124+
.bodyStyle()
125+
}
108126
}
109127
.buttonStyle(SecondaryButtonStyle())
110128
.padding(.horizontal, Constants.margin)
111129
}
130+
.padding(.bottom, Constants.verticalSpacing)
112131

113132
Group {
114133
ListHeaderView(text: Localization.headerUsageDetails.uppercased(), alignment: .left)
@@ -119,6 +138,7 @@ struct AddEditCoupon: View {
119138
Divider()
120139
.padding(.leading, Constants.margin)
121140
}
141+
.padding(.bottom, Constants.verticalSpacing)
122142

123143
Button {
124144
//TODO: handle action
@@ -127,7 +147,7 @@ struct AddEditCoupon: View {
127147
}
128148
.buttonStyle(PrimaryButtonStyle())
129149
.padding(.horizontal, Constants.margin)
130-
.padding(.top, Constants.verticalSpacing)
150+
.padding([.top, .bottom], Constants.verticalSpacing)
131151
}
132152
}
133153
.ignoresSafeArea(.container, edges: [.horizontal, .bottom])
@@ -153,6 +173,7 @@ private extension AddEditCoupon {
153173
enum Constants {
154174
static let margin: CGFloat = 16
155175
static let verticalSpacing: CGFloat = 8
176+
static let iconSize: CGFloat = 16
156177
}
157178

158179
enum Localization {
@@ -162,23 +183,20 @@ private extension AddEditCoupon {
162183
static let headerCouponDetails = NSLocalizedString(
163184
"Coupon details",
164185
comment: "Header of the coupon details in the view for adding or editing a coupon.")
165-
static let couponAmountPercentage = NSLocalizedString(
166-
"Amount (%)",
167-
comment: "Text field Amount in percentage in the view for adding or editing a coupon.")
168-
static let footerCouponAmountPercentage = NSLocalizedString(
169-
"Set the percentage of the discount you want to offer.",
170-
comment: "The footer of the text field Amount in percentage in the view for adding or editing a coupon.")
171186
static let couponCode = NSLocalizedString(
172187
"Coupon Code",
173188
comment: "Text field coupon code in the view for adding or editing a coupon.")
189+
static let couponCodePlaceholder = NSLocalizedString(
190+
"Enter a coupon",
191+
comment: "Text field coupon code placeholder in the view for adding or editing a coupon.")
174192
static let footerCouponCode = NSLocalizedString(
175193
"Customers need to enter this code to use the coupon.",
176194
comment: "The footer of the text field coupon code in the view for adding or editing a coupon.")
177195
static let regenerateCouponCodeButton = NSLocalizedString(
178196
"Regenerate Coupon Code",
179197
comment: "Button in the view for adding or editing a coupon.")
180198
static let addDescriptionButton = NSLocalizedString(
181-
"+ Add Description (Optional)",
199+
"Add Description (Optional)",
182200
comment: "Button for adding a description to a coupon in the view for adding or editing a coupon.")
183201
static let couponExpiryDate = NSLocalizedString(
184202
"Coupon Expiry Date",

WooCommerce/Classes/ViewRelated/Coupons/Add and Edit Coupons/AddEditCouponViewModel.swift

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,32 @@ final class AddEditCouponViewModel: ObservableObject {
2222
}
2323
}
2424

25-
private var coupon: Coupon? {
26-
didSet {
27-
amountField = coupon?.amount ?? ""
28-
codeField = coupon?.code ?? ""
25+
/// Label representing the label of the amount field, localized based on discount type.
26+
///
27+
var amountLabel: String {
28+
switch discountType {
29+
case .percent:
30+
return Localization.amountPercent
31+
default:
32+
let currencyCode = ServiceLocator.currencySettings.currencyCode
33+
let unit = ServiceLocator.currencySettings.symbol(from: currencyCode)
34+
return String.localizedStringWithFormat(Localization.amountFixedDiscount, unit)
35+
}
36+
}
37+
38+
/// Label representing the label of the amount textfield subtitle, localized based on discount type.
39+
///
40+
var amountSubtitleLabel: String {
41+
switch discountType {
42+
case .percent:
43+
return Localization.amountPercentSubtitle
44+
default:
45+
return Localization.amountFixedDiscountSubtitle
2946
}
3047
}
3148

49+
private var coupon: Coupon?
50+
3251
// Fields
3352
@Published var amountField = String()
3453
@Published var codeField = String()
@@ -49,10 +68,35 @@ final class AddEditCouponViewModel: ObservableObject {
4968
coupon = existingCoupon
5069
editingOption = .editing
5170
discountType = existingCoupon.discountType
71+
72+
// Populate fields
73+
amountField = existingCoupon.amount
74+
codeField = existingCoupon.code
5275
}
5376

5477
private enum EditingOption {
5578
case creation
5679
case editing
5780
}
5881
}
82+
83+
// MARK: - Constants
84+
//
85+
private extension AddEditCouponViewModel {
86+
87+
enum Localization {
88+
static let amountPercent = NSLocalizedString("Amount (%)",
89+
comment: "Title of the Amount field in the Coupon Edit" +
90+
" or Creation screen for a percentage discount coupon.")
91+
static let amountFixedDiscount = NSLocalizedString("Amount (%@)",
92+
comment: "Title of the Amount field on the Coupon Edit" +
93+
" or Creation screen for a fixed amount discount coupon." +
94+
"Reads like: Amount ($)")
95+
static let amountPercentSubtitle = NSLocalizedString("Set the percentage of the discount you want to offer.",
96+
comment: "Subtitle of the Amount field in the Coupon Edit" +
97+
" or Creation screen for a percentage discount coupon.")
98+
static let amountFixedDiscountSubtitle = NSLocalizedString("Set the fixed amount of the discount you want to offer.",
99+
comment: "Subtitle of the Amount field on the Coupon Edit" +
100+
" or Creation screen for a fixed amount discount coupon.")
101+
}
102+
}

WooCommerce/WooCommerceTests/ViewRelated/Coupons/AddEditCouponViewModelTests.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ final class AddEditCouponViewModelTests: XCTestCase {
99
XCTAssertEqual(viewModel1.title, Localization.titleCreatePercentageDiscount)
1010

1111
let viewModel2 = AddEditCouponViewModel(siteID: 123, discountType: .fixedCart)
12-
XCTAssertEqual(viewModel2.title, Localization.titleCreateFixedCardDiscount)
12+
XCTAssertEqual(viewModel2.title, Localization.titleCreateFixedCartDiscount)
1313

1414
let viewModel3 = AddEditCouponViewModel(siteID: 123, discountType: .fixedProduct)
1515
XCTAssertEqual(viewModel3.title, Localization.titleCreateFixedProductDiscount)
@@ -23,7 +23,7 @@ final class AddEditCouponViewModelTests: XCTestCase {
2323
XCTAssertEqual(viewModel1.title, Localization.titleEditPercentageDiscount)
2424

2525
let viewModel2 = AddEditCouponViewModel(existingCoupon: Coupon.sampleCoupon.copy(discountType: .fixedCart))
26-
XCTAssertEqual(viewModel2.title, Localization.titleEditFixedCardDiscount)
26+
XCTAssertEqual(viewModel2.title, Localization.titleEditFixedCartDiscount)
2727

2828
let viewModel3 = AddEditCouponViewModel(existingCoupon: Coupon.sampleCoupon.copy(discountType: .fixedProduct))
2929
XCTAssertEqual(viewModel3.title, Localization.titleEditFixedProductDiscount)
@@ -36,9 +36,9 @@ final class AddEditCouponViewModelTests: XCTestCase {
3636
static let titleCreatePercentageDiscount = NSLocalizedString(
3737
"Create percentage discount",
3838
comment: "Title of the view for creating a coupon with percentage discount.")
39-
static let titleCreateFixedCardDiscount = NSLocalizedString(
40-
"Create fixed card discount",
41-
comment: "Title of the view for creating a coupon with fixed card discount.")
39+
static let titleCreateFixedCartDiscount = NSLocalizedString(
40+
"Create fixed cart discount",
41+
comment: "Title of the view for creating a coupon with fixed cart discount.")
4242
static let titleCreateFixedProductDiscount = NSLocalizedString(
4343
"Create fixed product discount",
4444
comment: "Title of the view for creating a coupon with fixed product discount.")
@@ -48,9 +48,9 @@ final class AddEditCouponViewModelTests: XCTestCase {
4848
static let titleEditPercentageDiscount = NSLocalizedString(
4949
"Edit percentage discount",
5050
comment: "Title of the view for editing a coupon with percentage discount.")
51-
static let titleEditFixedCardDiscount = NSLocalizedString(
52-
"Edit fixed card discount",
53-
comment: "Title of the view for editing a coupon with fixed card discount.")
51+
static let titleEditFixedCartDiscount = NSLocalizedString(
52+
"Edit fixed cart discount",
53+
comment: "Title of the view for editing a coupon with fixed cart discount.")
5454
static let titleEditFixedProductDiscount = NSLocalizedString(
5555
"Edit fixed product discount",
5656
comment: "Title of the view for editing a coupon with fixed product discount.")

0 commit comments

Comments
 (0)