@@ -9,7 +9,7 @@ final class CouponDetailsHostingController: UIHostingController<CouponDetails> {
99 super. init ( rootView: CouponDetails ( viewModel: viewModel, onDeletion: onDeletion) )
1010 // The navigation title is set here instead of the SwiftUI view's `navigationTitle`
1111 // to avoid the blinking of the title label when pushed from UIKit view.
12- title = NSLocalizedString ( " Coupon " , comment : " Title of Coupon Details screen " )
12+ title = viewModel . couponCode
1313
1414 // Set presenting view controller to show the notice presenter here
1515 rootView. noticePresenter. presentingViewController = self
@@ -50,16 +50,6 @@ struct CouponDetails: View {
5050 ServiceLocator . analytics. track ( . couponDetails, withProperties: [ " action " : " loaded " ] )
5151 }
5252
53- private var detailRows : [ DetailRow ] {
54- [
55- . init( title: Localization . couponCode, content: viewModel. couponCode, action: { } ) ,
56- . init( title: Localization . description, content: viewModel. description, action: { } ) ,
57- . init( title: Localization . discount, content: viewModel. amount, action: { } ) ,
58- . init( title: Localization . applyTo, content: viewModel. productsAppliedTo, action: { } ) ,
59- . init( title: Localization . expiryDate, content: viewModel. expiryDate, action: { } )
60- ]
61- }
62-
6353 private var actionSheetButtons : [ Alert . Button ] {
6454 var buttons : [ Alert . Button ] =
6555 [
@@ -111,11 +101,41 @@ struct CouponDetails: View {
111101 ShareSheet ( activityItems: [ viewModel. shareMessage] )
112102 }
113103
104+ VStack ( alignment: . leading, spacing: Constants . verticalSpacing) {
105+ Text ( viewModel. couponCode)
106+ . font ( . title2)
107+ . bold ( )
108+ StatusView ( label: viewModel. expiryStatus,
109+ backgroundColor: viewModel. expiryStatusBackgroundColor)
110+ }
111+ . padding ( . horizontal, insets: geometry. safeAreaInsets)
112+ . padding ( . horizontal, Constants . margin)
113+ . padding ( . vertical, Constants . summarySectionVerticalSpacing)
114+
115+ Text ( viewModel. description)
116+ . bold ( )
117+ . footnoteStyle ( )
118+ . renderedIf ( viewModel. description. isNotEmpty)
119+ . padding ( . horizontal, insets: geometry. safeAreaInsets)
120+ . padding ( . horizontal, Constants . margin)
121+ . padding ( . bottom, Constants . summarySectionVerticalSpacing)
122+
123+ Divider ( )
124+
125+ summarySection
126+ . padding ( . horizontal, insets: geometry. safeAreaInsets)
127+ . frame ( maxWidth: . infinity, alignment: . leading)
128+ . padding ( . bottom, Constants . margin)
129+ . background ( Color ( . listForeground) )
130+
131+ Divider ( )
132+ Spacer ( ) . frame ( height: Constants . margin)
133+ Divider ( )
134+
114135 VStack ( alignment: . leading, spacing: 0 ) {
115136 Text ( Localization . performance)
116137 . bold ( )
117138 . padding ( Constants . margin)
118- . padding ( . horizontal, insets: geometry. safeAreaInsets)
119139 VStack ( alignment: . leading, spacing: Constants . verticalSpacing) {
120140 HStack ( alignment: . firstTextBaseline) {
121141 Text ( Localization . discountedOrders)
@@ -151,51 +171,18 @@ struct CouponDetails: View {
151171 }
152172 }
153173 }
174+ . padding ( . horizontal, insets: geometry. safeAreaInsets)
154175 . padding ( . bottom, Constants . margin)
155176 . background ( Color ( . listForeground) )
156177
157178 Divider ( )
158- Spacer ( ) . frame ( height: Constants . margin)
159- Divider ( )
160-
161- VStack ( alignment: . leading, spacing: 0 ) {
162- Text ( Localization . detailSectionTitle)
163- . bold ( )
164- . padding ( Constants . margin)
165- . padding ( . horizontal, insets: geometry. safeAreaInsets)
166- ForEach ( detailRows) { row in
167- TitleAndValueRow ( title: row. title,
168- value: . content( row. content) ,
169- selectionStyle: . none,
170- action: row. action)
171- . padding ( . vertical, Constants . verticalSpacing)
172- . padding ( . horizontal, insets: geometry. safeAreaInsets)
173- Divider ( )
174- . padding ( . leading, Constants . margin)
175- . padding ( . leading, insets: geometry. safeAreaInsets)
176- }
177- }
178- . background ( Color ( . listForeground) )
179-
180- Spacer ( ) . frame ( height: Constants . margin)
181- Divider ( )
182- VStack {
183- NavigationRow ( content: {
184- Text ( Localization . usageDetails)
185- . bodyStyle ( )
186- } , action: {
187- showingUsageDetails = true
188- } ) . padding ( . horizontal, insets: geometry. safeAreaInsets)
189- }
190- . background ( Color ( . listForeground) )
191- Divider ( )
192179 }
193180 NavigationLink ( destination: CouponUsageDetails ( viewModel: . init( coupon: viewModel. coupon) ) , isActive: $showingUsageDetails) {
194181 EmptyView ( )
195182 } . hidden ( )
196183 }
197184 . background ( Color ( . listBackground) )
198- . ignoresSafeArea ( . container, edges: [ . horizontal, . bottom ] )
185+ . ignoresSafeArea ( . container, edges: [ . horizontal] )
199186 . sheet ( isPresented: $showingEnableAnalytics) {
200187 EnableAnalyticsView ( viewModel: . init( siteID: viewModel. siteID) ,
201188 presentingController: noticePresenter. presentingViewController,
@@ -230,6 +217,54 @@ struct CouponDetails: View {
230217 . wooNavigationBarStyle ( )
231218 }
232219
220+ private var summarySection : some View {
221+ VStack ( alignment: . leading, spacing: Constants . summarySectionVerticalSpacing) {
222+ Text ( Localization . summarySectionTitle)
223+ . bold ( )
224+ . padding ( . top, Constants . margin)
225+
226+ VStack ( alignment: . leading, spacing: Constants . summarySectionVerticalSpacing) {
227+ Text ( viewModel. discountType)
228+
229+ Text ( viewModel. summary)
230+
231+ Text ( Localization . individualUse)
232+ . renderedIf ( viewModel. individualUseOnly)
233+
234+ Text ( Localization . allowsFreeShipping)
235+ . renderedIf ( viewModel. allowsFreeShipping)
236+
237+ Text ( Localization . excludesSaleItems)
238+ . renderedIf ( viewModel. excludeSaleItems)
239+ }
240+
241+ VStack ( alignment: . leading, spacing: Constants . summarySectionVerticalSpacing) {
242+ Text ( String . localizedStringWithFormat ( Localization . minimumSpend, viewModel. minimumAmount) )
243+ . renderedIf ( viewModel. minimumAmount. isNotEmpty)
244+
245+ Text ( String . localizedStringWithFormat ( Localization . maximumSpend, viewModel. maximumAmount) )
246+ . renderedIf ( viewModel. maximumAmount. isNotEmpty)
247+
248+ Text ( String . localizedStringWithFormat ( Localization . singularLimitPerUser, viewModel. usageLimitPerUser) )
249+ . renderedIf ( viewModel. usageLimitPerUser == 1 )
250+
251+ Text ( String . localizedStringWithFormat ( Localization . pluralLimitPerUser, viewModel. usageLimitPerUser) )
252+ . renderedIf ( viewModel. usageLimitPerUser > 1 )
253+ }
254+ . renderedIf ( viewModel. minimumAmount. isNotEmpty ||
255+ viewModel. maximumAmount. isNotEmpty ||
256+ viewModel. usageLimitPerUser > 0 )
257+
258+ Text ( String . localizedStringWithFormat ( Localization . expiryFormat, viewModel. expiryDate) )
259+ . renderedIf ( viewModel. expiryDate. isNotEmpty)
260+
261+ Text ( String . localizedStringWithFormat ( Localization . emailRestriction, viewModel. emailRestrictions. joined ( separator: " , " ) ) )
262+ . renderedIf ( viewModel. emailRestrictions. isNotEmpty)
263+ }
264+ . bodyStyle ( )
265+ . padding ( . horizontal, Constants . margin)
266+ }
267+
233268 @ViewBuilder
234269 private var amountTitleView : some View {
235270 Text ( Localization . amount)
@@ -296,15 +331,49 @@ private extension CouponDetails {
296331 static let verticalSpacing : CGFloat = 8
297332 static let errorIconSize : CGFloat = 20
298333 static let errorIconHorizontalPadding : CGFloat = 4
334+ static let summarySectionVerticalSpacing : CGFloat = 24
299335 }
300336
301337 enum Localization {
302- static let detailSectionTitle = NSLocalizedString ( " Coupon Details " , comment: " Title of Details section in Coupon Details screen " )
303- static let couponCode = NSLocalizedString ( " Coupon Code " , comment: " Title of the Coupon Code row in Coupon Details screen " )
304- static let description = NSLocalizedString ( " Description " , comment: " Title of the Description row in Coupon Details screen " )
305- static let discount = NSLocalizedString ( " Discount " , comment: " Title of the Discount row in Coupon Details screen " )
306- static let applyTo = NSLocalizedString ( " Apply To " , comment: " Title of the Apply To row in Coupon Details screen " )
307- static let expiryDate = NSLocalizedString ( " Coupon Expiry Date " , comment: " Title of the Coupon Expiry Date row in Coupon Details screen " )
338+ static let summarySectionTitle = NSLocalizedString ( " Coupon Summary " , comment: " Title of Summary section in Coupon Details screen " )
339+ static let expiryFormat = NSLocalizedString (
340+ " Expires %1$@ " ,
341+ comment: " Formatted content for coupon expiry date, reads like: Expires August 4, 2022 "
342+ )
343+ static let allowsFreeShipping = NSLocalizedString (
344+ " Allows free shipping " ,
345+ comment: " Text on Coupon Details screen to indicate that the coupon allows free shipping "
346+ )
347+ static let excludesSaleItems = NSLocalizedString (
348+ " Excludes sale items " ,
349+ comment: " Text on Coupon Details screen to indicate that the coupon can not be applied to sale items "
350+ )
351+ static let individualUse = NSLocalizedString (
352+ " Individual use only " ,
353+ comment: " Text on Coupon Details screen to indicate that the coupon can not be applied in conjunction with other coupons "
354+ )
355+ static let minimumSpend = NSLocalizedString (
356+ " Minimum spend of %1$@ " ,
357+ comment: " The minimum limit of spending required for a coupon on the Coupon Details screen, reads like: Minimum spend of $20.00 "
358+ )
359+ static let maximumSpend = NSLocalizedString (
360+ " Maximum spend of %1$@ " ,
361+ comment: " The maximum limit of spending allowed for a coupon on the Coupon Details screen, reads like: Minimum spend of $20.00 "
362+ )
363+ static let singularLimitPerUser = NSLocalizedString (
364+ " %1$d use per user " ,
365+ comment: " The singular limit of time for each user to apply a coupon, reads like: 1 use per user "
366+ )
367+ static let pluralLimitPerUser = NSLocalizedString (
368+ " %1$d uses per user " ,
369+ comment: " The plural limit of time for each user to apply a coupon, reads like: 10 uses per user "
370+ )
371+ static let emailRestriction = NSLocalizedString (
372+ " Restricted to customers with emails: %1$@ " ,
373+ comment: " Restriction for customers with specified emails to use a coupon, " +
374+ " reads like: Restricted to customers with emails: *@a8c.com, *@vip.com "
375+ )
376+
308377 static let manageCoupon = NSLocalizedString ( " Manage Coupon " , comment: " Title of the action sheet displayed from the Coupon Details screen " )
309378 static let copyCode = NSLocalizedString ( " Copy Code " , comment: " Action title for copying coupon code from the Coupon Details screen " )
310379 static let couponCopied = NSLocalizedString ( " Coupon copied " , comment: " Notice message displayed when a coupon code is " +
0 commit comments