@@ -32,8 +32,8 @@ struct POSOrderDetailsView: View {
3232 title: POSOrderListView . Localization. orderTitle ( order. number) ,
3333 backButtonConfiguration: shouldShowBackButton ? . init( state: . enabled, action: onBack) : nil ,
3434 trailingContent: {
35- if actions . isNotEmpty {
36- actionsSection ( actions )
35+ if primaryAction != nil || overflowActions . isNotEmpty {
36+ actionsSection ( overflowActions )
3737 }
3838 } ,
3939 bottomContent: {
@@ -377,7 +377,24 @@ private extension POSOrderDetailsView {
377377
378378// MARK: - Actions
379379private extension POSOrderDetailsView {
380- enum POSOrderDetailsAction : Identifiable , CaseIterable {
380+ // Primary action for the header
381+ enum POSPrimaryAction {
382+ case issueRefund
383+
384+ var title : String {
385+ switch self {
386+ case . issueRefund:
387+ Localization . issueRefundActionTitle
388+ }
389+ }
390+
391+ func available( for order: POSOrder ) -> Bool {
392+ // Adjust the condition as needed
393+ return order. status == . completed
394+ }
395+ }
396+
397+ enum POSOverflowAction : Identifiable , CaseIterable {
381398 case emailReceipt
382399
383400 var id : String { title }
@@ -392,43 +409,53 @@ private extension POSOrderDetailsView {
392409 func available( for order: POSOrder ) -> Bool {
393410 switch self {
394411 case . emailReceipt:
395- order. status == . completed
412+ return order. status == . completed
396413 }
397414 }
398415 }
399416
400- var actions : [ POSOrderDetailsAction ] {
401- POSOrderDetailsAction . allCases. filter { $0. available ( for: order) }
417+ // Primary + overflow actions (formerly `actions`)
418+ var primaryAction : POSPrimaryAction ? {
419+ let candidate : POSPrimaryAction = . issueRefund
420+ return candidate. available ( for: order) ? candidate : nil
421+ }
422+
423+ var overflowActions : [ POSOverflowAction ] {
424+ POSOverflowAction . allCases. filter { $0. available ( for: order) }
402425 }
403426
404427 @ViewBuilder
405- func actionsSection( _ actions: [ POSOrderDetailsAction ] ) -> some View {
406- VStack {
407- HStack {
408- ForEach ( actions) { action in
409- Button ( action: {
428+ func actionsSection( _ actions: [ POSOverflowAction ] ) -> some View {
429+ HStack ( spacing: POSSpacing . large) {
430+ if let primaryAction {
431+ Button ( primaryAction. title) { }
432+ . buttonStyle ( POSFilledButtonStyle ( size: . extraSmall) )
433+ . accessibilityHint ( Localization . issueRefundAccessibilityHint)
434+ . lineLimit ( 1 )
435+ . minimumScaleFactor ( 0.5 )
436+ }
437+
438+ if overflowActions. isNotEmpty {
439+ Menu {
440+ ForEach ( overflowActions) { action in
410441 switch action {
411442 case . emailReceipt:
412- analytics. track ( event: WooAnalyticsEvent . PointOfSale. orderDetailsEmailReceiptTapped ( ) )
413- isShowingEmailReceiptView = true
443+ Button ( action. title) {
444+ analytics. track ( event: WooAnalyticsEvent . PointOfSale. orderDetailsEmailReceiptTapped ( ) )
445+ isShowingEmailReceiptView = true
446+ }
447+ . accessibilityHint ( Localization . emailReceiptAccessibilityHint)
414448 }
415- } ) {
416- Text ( Localization . emailReceiptActionTitle)
417- . lineLimit ( 1 )
418- . minimumScaleFactor ( 0.5 )
419449 }
420- . buttonStyle ( POSFilledButtonStyle ( size: . extraSmall) )
421- . accessibilityHint ( accessibilityHint ( for: action) )
450+ } label: {
451+ Image ( systemName: " ellipsis " )
452+ . font ( . posBodyLargeBold)
453+ . dynamicTypeSize ( ... DynamicTypeSize . accessibility2)
454+ . foregroundColor ( . posOnSurface)
455+ . padding ( POSPadding . small)
422456 }
457+ . menuIndicator ( . hidden)
423458 }
424- Spacer ( )
425- }
426- }
427-
428- private func accessibilityHint( for action: POSOrderDetailsAction ) -> String {
429- switch action {
430- case . emailReceipt:
431- return Localization . emailReceiptAccessibilityHint
432459 }
433460 }
434461}
@@ -529,6 +556,24 @@ private enum Localization {
529556 comment: " Accessibility hint for email receipt button on order details view "
530557 )
531558
559+ static let issueRefundActionTitle = NSLocalizedString (
560+ " pos.orderDetailsView.issueRefundAction.title " ,
561+ value: " Issue refund " ,
562+ comment: " Primary action button to start issuing a refund on the order details view "
563+ )
564+
565+ static let issueRefundAccessibilityHint = NSLocalizedString (
566+ " pos.orderDetailsView.issueRefundAction.accessibilityHint " ,
567+ value: " Start refund flow for this order " ,
568+ comment: " Accessibility hint for issue refund button "
569+ )
570+
571+ static let moreActionsA11yLabel = NSLocalizedString (
572+ " pos.orderDetailsView.moreActions.label " ,
573+ value: " More actions " ,
574+ comment: " Accessibility label for the overflow actions menu button (three dots) "
575+ )
576+
532577 static func headerBottomContentAccessibilityLabel( date: String , email: String ? , status: String ) -> String {
533578 let baseFormat = NSLocalizedString (
534579 " pos.orderDetailsView.headerBottomContent.accessibilityLabel " ,
0 commit comments