@@ -7,79 +7,106 @@ struct POSIneligibleView: View {
77 let reason : POSIneligibleReason
88 let onRefresh : ( ) async throws -> Void
99 @Environment ( \. dismiss) private var dismiss
10+ @Environment ( \. sizeCategory) private var sizeCategory
1011 @State private var isLoading : Bool = false
12+ @State private var scrollViewHeight : CGFloat = 0
13+ @State private var contentHeight : CGFloat = 0
1114
12- var body : some View {
13- VStack ( spacing: POSSpacing . none) {
14- Spacer ( )
15+ /// Returns the frame width multiplier for the content view based on accessibility size category.
16+ private var frameWidthMultiplier : Double {
17+ if sizeCategory >= . accessibilityMedium {
18+ return 0.9 // Use more horizontal space for larger accessibility sizes
19+ } else {
20+ return 0.5 // Standard multiplier for regular sizes
21+ }
22+ }
1523
16- VStack ( alignment: . center, spacing: POSSpacing . none) {
17- POSErrorXMark ( )
24+ /// Returns true if scrolling should be disabled (content fits within scroll view).
25+ private var shouldDisableScrolling : Bool {
26+ scrollViewHeight > 0 && contentHeight > 0 && contentHeight <= scrollViewHeight
27+ }
1828
29+ var body : some View {
30+ ScrollView {
31+ VStack ( spacing: POSSpacing . none) {
1932 Spacer ( )
20- . frame ( height: POSSpacing . medium)
21-
22- VStack ( spacing: POSSpacing . small) {
23- Text ( Localization . title)
24- . font ( POSFontStyle . posHeadingBold. font ( ) )
25- . multilineTextAlignment ( . center)
26- . foregroundColor ( Color . posOnSurface)
27-
28- Text ( suggestionText)
29- . font ( POSFontStyle . posBodyLargeRegular ( ) . font ( ) )
30- . multilineTextAlignment ( . center)
31- . foregroundColor ( Color . posOnSurface)
32- }
33- . containerRelativeFrame ( . horizontal) { length, _ in
34- max ( length * 0.5 , 300 )
35- }
3633
37- Spacer ( )
38- . frame ( height: POSSpacing . large)
39-
40- VStack ( spacing: POSSpacing . medium) {
41- Button {
42- Task { @MainActor in
43- do {
44- isLoading = true
45- ServiceLocator . analytics. track (
46- event: . PointOfSaleIneligibleUI. ineligibleUIRetryTapped ( reason: reason)
47- )
48- try await onRefresh ( )
49- isLoading = false
50- } catch {
51- // TODO: WOOMOB-720 - handle error if needed, e.g., show an error message
52- DDLogError ( " Error refreshing eligibility: \( error) " )
53- isLoading = false
34+ VStack ( alignment: . center, spacing: POSSpacing . none) {
35+ POSErrorXMark ( )
36+
37+ Spacer ( )
38+ . frame ( height: POSSpacing . medium)
39+
40+ VStack ( spacing: POSSpacing . small) {
41+ Text ( Localization . title)
42+ . font ( POSFontStyle . posHeadingBold. font ( ) )
43+ . multilineTextAlignment ( . center)
44+ . foregroundColor ( Color . posOnSurface)
45+
46+ Text ( suggestionText)
47+ . font ( POSFontStyle . posBodyLargeRegular ( ) . font ( ) )
48+ . multilineTextAlignment ( . center)
49+ . foregroundColor ( Color . posOnSurface)
50+ }
51+ . containerRelativeFrame ( . horizontal) { length, _ in
52+ max ( length * frameWidthMultiplier, 300 )
53+ }
54+
55+ Spacer ( )
56+ . frame ( height: POSSpacing . large)
57+
58+ VStack ( spacing: POSSpacing . medium) {
59+ Button {
60+ Task { @MainActor in
61+ do {
62+ isLoading = true
63+ ServiceLocator . analytics. track (
64+ event: . PointOfSaleIneligibleUI. ineligibleUIRetryTapped ( reason: reason)
65+ )
66+ try await onRefresh ( )
67+ isLoading = false
68+ } catch {
69+ DDLogError ( " Error refreshing eligibility: \( error) " )
70+ isLoading = false
71+ }
5472 }
73+ } label: {
74+ Text ( reason. refreshEligibilityTitle)
5575 }
56- } label: {
57- Text ( reason. refreshEligibilityTitle)
58- }
59- . buttonStyle ( POSFilledButtonStyle ( size: . normal, isLoading: isLoading) )
60- . renderedIf ( reason. shouldShowRetryButton)
76+ . buttonStyle ( POSFilledButtonStyle ( size: . normal, isLoading: isLoading) )
77+ . renderedIf ( reason. shouldShowRetryButton)
6178
62- Button {
63- dismiss ( )
64- } label: {
65- Text ( Localization . dismiss)
79+ Button {
80+ dismiss ( )
81+ } label: {
82+ Text ( Localization . dismiss)
83+ }
84+ . buttonStyle ( POSOutlinedButtonStyle ( size: . normal) )
85+ }
86+ . containerRelativeFrame ( . horizontal) { length, _ in
87+ max ( length * frameWidthMultiplier - 132 , 300 )
6688 }
67- . buttonStyle ( POSOutlinedButtonStyle ( size: . normal) )
68- }
69- . containerRelativeFrame ( . horizontal) { length, _ in
70- max ( length * 0.5 - 132 , 300 )
7189 }
72- }
7390
74- Spacer ( )
75- }
76- . padding ( POSPadding . large)
77- . onAppear {
78- ServiceLocator . analytics. track ( event: . PointOfSaleIneligibleUI. ineligibleUIShown ( reason: reason) )
91+ Spacer ( )
92+ }
93+ . padding ( POSPadding . large)
94+ . frame ( maxWidth: . infinity, minHeight: scrollViewHeight > 0 ? scrollViewHeight : nil )
95+ . measureHeight { height in
96+ contentHeight = height
97+ }
98+ . onAppear {
99+ ServiceLocator . analytics. track ( event: . PointOfSaleIneligibleUI. ineligibleUIShown ( reason: reason) )
100+ }
101+ . onChange ( of: reason) { newReason in
102+ ServiceLocator . analytics. track ( event: . PointOfSaleIneligibleUI. ineligibleUIShown ( reason: newReason) )
103+ }
79104 }
80- . onChange ( of: reason) { newReason in
81- ServiceLocator . analytics. track ( event: . PointOfSaleIneligibleUI. ineligibleUIShown ( reason: newReason) )
105+ . scrollDisabled ( shouldDisableScrolling)
106+ . measureHeight { height in
107+ scrollViewHeight = height
82108 }
109+ . frame ( maxWidth: . infinity, maxHeight: . infinity)
83110 }
84111
85112 private var suggestionText : String {
0 commit comments