Skip to content

Commit 84cb276

Browse files
authored
[POS Refunds] Order details button (#16414)
2 parents d846bd2 + 1083d9a commit 84cb276

File tree

1 file changed

+91
-31
lines changed

1 file changed

+91
-31
lines changed

Modules/Sources/PointOfSale/Presentation/Orders/POSOrderDetailsView.swift

Lines changed: 91 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct POSOrderDetailsView: View {
1414
@Environment(\.siteTimezone) private var siteTimezone
1515
@Environment(POSOrderListModel.self) private var orderListModel
1616
@Environment(\.posAnalytics) private var analytics
17+
@Environment(\.posFeatureFlags) private var featureFlags
1718
@State private var isShowingEmailReceiptView: Bool = false
1819

1920
private var shouldShowBackButton: Bool {
@@ -32,9 +33,7 @@ struct POSOrderDetailsView: View {
3233
title: POSOrderListView.Localization.orderTitle(order.number),
3334
backButtonConfiguration: shouldShowBackButton ? .init(state: .enabled, action: onBack) : nil,
3435
trailingContent: {
35-
if actions.isNotEmpty {
36-
actionsSection(actions)
37-
}
36+
actionsSection(setup: availableActionsSetup)
3837
},
3938
bottomContent: {
4039
headerBottomContent(for: order)
@@ -377,59 +376,102 @@ private extension POSOrderDetailsView {
377376

378377
// MARK: - Actions
379378
private extension POSOrderDetailsView {
380-
enum POSOrderDetailsAction: Identifiable, CaseIterable {
379+
enum OrderDetailsAction: Identifiable, CaseIterable {
380+
case issueRefund
381381
case emailReceipt
382382

383383
var id: String { title }
384384

385385
var title: String {
386386
switch self {
387-
case .emailReceipt:
388-
Localization.emailReceiptActionTitle
387+
case .issueRefund: Localization.issueRefundActionTitle
388+
case .emailReceipt: Localization.emailReceiptActionTitle
389389
}
390390
}
391391

392-
func available(for order: POSOrder) -> Bool {
392+
var accessibilityHint: String {
393393
switch self {
394+
case .issueRefund: Localization.issueRefundAccessibilityHint
395+
case .emailReceipt: Localization.emailReceiptAccessibilityHint
396+
}
397+
}
398+
399+
var priority: Int {
400+
switch self {
401+
case .issueRefund: 100
402+
case .emailReceipt: 50
403+
}
404+
}
405+
406+
func isAvailable(for order: POSOrder, flags: POSFeatureFlagProviding) -> Bool {
407+
guard order.status == .completed else { return false }
408+
switch self {
409+
case .issueRefund:
410+
return flags.isFeatureFlagEnabled(.pointOfSaleRefundsi1)
394411
case .emailReceipt:
395-
order.status == .completed
412+
return true
413+
}
414+
}
415+
}
416+
417+
func handler(for action: OrderDetailsAction) -> @MainActor () -> Void {
418+
switch action {
419+
case .emailReceipt:
420+
return {
421+
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
422+
isShowingEmailReceiptView = true
396423
}
424+
case .issueRefund:
425+
return { }
397426
}
398427
}
399428

400-
var actions: [POSOrderDetailsAction] {
401-
POSOrderDetailsAction.allCases.filter { $0.available(for: order) }
429+
struct OrderDetailsActionsSetup {
430+
let primary: OrderDetailsAction?
431+
let secondary: [OrderDetailsAction]
432+
}
433+
434+
var availableActionsSetup: OrderDetailsActionsSetup {
435+
let available = OrderDetailsAction.allCases
436+
.filter { $0.isAvailable(for: order, flags: featureFlags) }
437+
.sorted { $0.priority > $1.priority }
438+
439+
let primary = available.first
440+
let secondary = Array(available.dropFirst())
441+
442+
return OrderDetailsActionsSetup(primary: primary, secondary: secondary)
402443
}
403444

404445
@ViewBuilder
405-
func actionsSection(_ actions: [POSOrderDetailsAction]) -> some View {
406-
VStack {
407-
HStack {
408-
ForEach(actions) { action in
409-
Button(action: {
410-
switch action {
411-
case .emailReceipt:
412-
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
413-
isShowingEmailReceiptView = true
446+
func actionsSection(setup: OrderDetailsActionsSetup) -> some View {
447+
if let primary = setup.primary {
448+
HStack(spacing: POSSpacing.large) {
449+
Button(primary.title, action: handler(for: primary))
450+
.buttonStyle(POSFilledButtonStyle(size: .extraSmall))
451+
.accessibilityHint(primary.accessibilityHint)
452+
453+
if !setup.secondary.isEmpty {
454+
Menu {
455+
ForEach(setup.secondary) { action in
456+
Button(action.title, action: handler(for: action))
457+
.accessibilityHint(action.accessibilityHint)
414458
}
415-
}) {
416-
Text(Localization.emailReceiptActionTitle)
417-
.lineLimit(1)
418-
.minimumScaleFactor(0.5)
459+
} label: {
460+
Image(systemName: "ellipsis")
461+
.font(.posBodyLargeBold)
462+
.dynamicTypeSize(...DynamicTypeSize.accessibility2)
463+
.foregroundColor(.posOnSurface)
464+
.padding(POSPadding.small)
419465
}
420-
.buttonStyle(POSFilledButtonStyle(size: .extraSmall))
421-
.accessibilityHint(accessibilityHint(for: action))
466+
.menuIndicator(.hidden)
422467
}
423468
}
424-
Spacer()
425469
}
426470
}
427471

428-
private func accessibilityHint(for action: POSOrderDetailsAction) -> String {
429-
switch action {
430-
case .emailReceipt:
431-
return Localization.emailReceiptAccessibilityHint
432-
}
472+
func emailReceiptAction() {
473+
analytics.track(event: WooAnalyticsEvent.PointOfSale.orderDetailsEmailReceiptTapped())
474+
isShowingEmailReceiptView = true
433475
}
434476
}
435477

@@ -529,6 +571,24 @@ private enum Localization {
529571
comment: "Accessibility hint for email receipt button on order details view"
530572
)
531573

574+
static let issueRefundActionTitle = NSLocalizedString(
575+
"pos.orderDetailsView.issueRefundAction.title",
576+
value: "Issue refund",
577+
comment: "Primary action button to start issuing a refund on the order details view"
578+
)
579+
580+
static let issueRefundAccessibilityHint = NSLocalizedString(
581+
"pos.orderDetailsView.issueRefundAction.accessibilityHint",
582+
value: "Start refund flow for this order",
583+
comment: "Accessibility hint for issue refund button"
584+
)
585+
586+
static let moreActionsA11yLabel = NSLocalizedString(
587+
"pos.orderDetailsView.moreActions.label",
588+
value: "More actions",
589+
comment: "Accessibility label for the overflow actions menu button (three dots)"
590+
)
591+
532592
static func headerBottomContentAccessibilityLabel(date: String, email: String?, status: String) -> String {
533593
let baseFormat = NSLocalizedString(
534594
"pos.orderDetailsView.headerBottomContent.accessibilityLabel",

0 commit comments

Comments
 (0)