@oxyhq/services 5.11.10 → 5.11.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/lib/commonjs/ui/components/AnimationExample.js +1 -1
  2. package/lib/commonjs/ui/components/AnimationExample.js.map +1 -1
  3. package/lib/commonjs/ui/components/Header.js +2 -2
  4. package/lib/commonjs/ui/components/Header.js.map +1 -1
  5. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  6. package/lib/commonjs/ui/components/StepBasedScreen.README.md +337 -0
  7. package/lib/commonjs/ui/components/StepBasedScreen.js +361 -0
  8. package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -0
  9. package/lib/commonjs/ui/components/icon/OxyIcon.js +3 -3
  10. package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
  11. package/lib/commonjs/ui/components/internal/PinInput.js +1 -1
  12. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
  13. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  14. package/lib/commonjs/ui/context/OxyContext.js +7 -7
  15. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  16. package/lib/commonjs/ui/screens/ProfileScreen.js +55 -55
  17. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  18. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +87 -219
  19. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  20. package/lib/commonjs/ui/screens/SignInScreen.js +138 -235
  21. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  22. package/lib/commonjs/ui/screens/SignUpScreen.js +139 -742
  23. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  24. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +3 -3
  25. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  26. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +2 -2
  27. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  28. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +110 -0
  29. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -0
  30. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +138 -0
  31. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
  32. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +141 -0
  33. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
  34. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +165 -0
  35. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -0
  36. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +150 -0
  37. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -0
  38. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +171 -0
  39. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
  40. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +163 -0
  41. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
  42. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +170 -0
  43. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
  44. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +72 -0
  45. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
  46. package/lib/module/ui/components/AnimationExample.js +1 -1
  47. package/lib/module/ui/components/AnimationExample.js.map +1 -1
  48. package/lib/module/ui/components/Header.js +2 -2
  49. package/lib/module/ui/components/Header.js.map +1 -1
  50. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  51. package/lib/module/ui/components/Section.js.map +1 -1
  52. package/lib/module/ui/components/SectionTitle.js.map +1 -1
  53. package/lib/module/ui/components/StepBasedScreen.README.md +337 -0
  54. package/lib/module/ui/components/StepBasedScreen.js +356 -0
  55. package/lib/module/ui/components/StepBasedScreen.js.map +1 -0
  56. package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -1
  57. package/lib/module/ui/components/icon/OxyIcon.js +3 -3
  58. package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
  59. package/lib/module/ui/components/internal/PinInput.js +1 -1
  60. package/lib/module/ui/components/internal/PinInput.js.map +1 -1
  61. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  62. package/lib/module/ui/context/OxyContext.js +7 -7
  63. package/lib/module/ui/context/OxyContext.js.map +1 -1
  64. package/lib/module/ui/screens/ProfileScreen.js +55 -55
  65. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  66. package/lib/module/ui/screens/RecoverAccountScreen.js +91 -222
  67. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  68. package/lib/module/ui/screens/SignInScreen.js +140 -237
  69. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  70. package/lib/module/ui/screens/SignUpScreen.js +141 -743
  71. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  72. package/lib/module/ui/screens/internal/SignInPasswordStep.js +3 -3
  73. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  74. package/lib/module/ui/screens/internal/SignInUsernameStep.js +2 -2
  75. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  76. package/lib/module/ui/screens/steps/RecoverRequestStep.js +105 -0
  77. package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -0
  78. package/lib/module/ui/screens/steps/RecoverSuccessStep.js +133 -0
  79. package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
  80. package/lib/module/ui/screens/steps/RecoverVerifyStep.js +136 -0
  81. package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
  82. package/lib/module/ui/screens/steps/SignInPasswordStep.js +160 -0
  83. package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -0
  84. package/lib/module/ui/screens/steps/SignInUsernameStep.js +145 -0
  85. package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -0
  86. package/lib/module/ui/screens/steps/SignUpIdentityStep.js +166 -0
  87. package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
  88. package/lib/module/ui/screens/steps/SignUpSecurityStep.js +158 -0
  89. package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
  90. package/lib/module/ui/screens/steps/SignUpSummaryStep.js +165 -0
  91. package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
  92. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +67 -0
  93. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
  94. package/lib/typescript/models/interfaces.d.ts +4 -3
  95. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  96. package/lib/typescript/ui/components/AnimationExample.d.ts +1 -1
  97. package/lib/typescript/ui/components/AnimationExample.d.ts.map +1 -1
  98. package/lib/typescript/ui/components/OxyPayButton.d.ts +2 -2
  99. package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -1
  100. package/lib/typescript/ui/components/Section.d.ts +2 -1
  101. package/lib/typescript/ui/components/Section.d.ts.map +1 -1
  102. package/lib/typescript/ui/components/SectionTitle.d.ts +2 -1
  103. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
  104. package/lib/typescript/ui/components/StepBasedScreen.d.ts +24 -0
  105. package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -0
  106. package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +2 -1
  107. package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -1
  108. package/lib/typescript/ui/components/icon/OxyIcon.d.ts +1 -1
  109. package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -1
  110. package/lib/typescript/ui/components/internal/PinInput.d.ts +9 -1
  111. package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
  112. package/lib/typescript/ui/context/OxyContext.d.ts +2 -1
  113. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  114. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +2 -2
  115. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  116. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  117. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +2 -9
  118. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  119. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  120. package/lib/typescript/ui/screens/SignUpScreen.d.ts +1 -1
  121. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  122. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +21 -0
  123. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -0
  124. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +18 -0
  125. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -0
  126. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +24 -0
  127. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -0
  128. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +27 -0
  129. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -0
  130. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +27 -0
  131. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -0
  132. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +25 -0
  133. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -0
  134. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +26 -0
  135. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -0
  136. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +16 -0
  137. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -0
  138. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +13 -0
  139. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -0
  140. package/package.json +2 -3
  141. package/src/models/interfaces.ts +5 -3
  142. package/src/ui/components/AnimationExample.tsx +9 -8
  143. package/src/ui/components/Header.tsx +2 -2
  144. package/src/ui/components/OxyPayButton.tsx +2 -2
  145. package/src/ui/components/OxyProvider.tsx +1 -1
  146. package/src/ui/components/Section.tsx +7 -7
  147. package/src/ui/components/SectionTitle.tsx +2 -2
  148. package/src/ui/components/StepBasedScreen.README.md +337 -0
  149. package/src/ui/components/StepBasedScreen.tsx +417 -0
  150. package/src/ui/components/icon/FAIRWalletIcon.tsx +2 -2
  151. package/src/ui/components/icon/OxyIcon.tsx +10 -11
  152. package/src/ui/components/internal/PinInput.tsx +13 -4
  153. package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +1 -1
  154. package/src/ui/context/OxyContext.tsx +12 -11
  155. package/src/ui/screens/PaymentGatewayScreen.tsx +2 -2
  156. package/src/ui/screens/ProfileScreen.tsx +54 -54
  157. package/src/ui/screens/RecoverAccountScreen.tsx +98 -211
  158. package/src/ui/screens/SignInScreen.tsx +148 -271
  159. package/src/ui/screens/SignUpScreen.tsx +146 -748
  160. package/src/ui/screens/internal/SignInPasswordStep.tsx +3 -3
  161. package/src/ui/screens/internal/SignInUsernameStep.tsx +2 -2
  162. package/src/ui/screens/steps/RecoverRequestStep.tsx +130 -0
  163. package/src/ui/screens/steps/RecoverSuccessStep.tsx +131 -0
  164. package/src/ui/screens/steps/RecoverVerifyStep.tsx +153 -0
  165. package/src/ui/screens/steps/SignInPasswordStep.tsx +172 -0
  166. package/src/ui/screens/steps/SignInUsernameStep.tsx +176 -0
  167. package/src/ui/screens/steps/SignUpIdentityStep.tsx +204 -0
  168. package/src/ui/screens/steps/SignUpSecurityStep.tsx +191 -0
  169. package/src/ui/screens/steps/SignUpSummaryStep.tsx +130 -0
  170. package/src/ui/screens/steps/SignUpWelcomeStep.tsx +65 -0
@@ -0,0 +1,417 @@
1
+ import type React from 'react';
2
+ import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
3
+ import {
4
+ View,
5
+ Text,
6
+ KeyboardAvoidingView,
7
+ ScrollView,
8
+ StatusBar,
9
+ Platform,
10
+ StyleSheet,
11
+ } from 'react-native';
12
+ import Animated, {
13
+ useSharedValue,
14
+ useAnimatedStyle,
15
+ withTiming,
16
+ withSequence,
17
+ withDelay,
18
+ withSpring,
19
+ runOnJS,
20
+ interpolate,
21
+ } from 'react-native-reanimated';
22
+ import { useThemeColors, createAuthStyles } from '../styles';
23
+ import type { BaseScreenProps } from '../navigation/types';
24
+
25
+ export interface StepConfig {
26
+ id: string;
27
+ component: React.ComponentType<any>;
28
+ props?: Record<string, any>;
29
+ canProceed?: (stepData?: any) => boolean;
30
+ onEnter?: () => void;
31
+ onExit?: () => void;
32
+ }
33
+
34
+ export interface StepBasedScreenProps extends Omit<BaseScreenProps, 'navigate'> {
35
+ steps: StepConfig[];
36
+ initialStep?: number;
37
+ showProgressIndicator?: boolean;
38
+ enableAnimations?: boolean;
39
+ onStepChange?: (currentStep: number, totalSteps: number) => void;
40
+ onComplete?: (stepData: any[]) => void;
41
+ stepData?: any[];
42
+ navigate: (screen: string, props?: Record<string, any>) => void;
43
+ oxyServices: any; // Required services for step components
44
+ }
45
+
46
+ interface StepBasedScreenState {
47
+ currentStep: number;
48
+ stepData: any[];
49
+ isTransitioning: boolean;
50
+ }
51
+
52
+ // Progress indicator component
53
+ const ProgressIndicator: React.FC<{
54
+ currentStep: number;
55
+ totalSteps: number;
56
+ colors: any;
57
+ styles: any;
58
+ }> = ({ currentStep, totalSteps, colors, styles }) => (
59
+ <View style={styles.progressContainer}>
60
+ {Array.from({ length: totalSteps }, (_, index) => (
61
+ <View
62
+ key={index}
63
+ style={[
64
+ styles.progressDot,
65
+ currentStep === index
66
+ ? { backgroundColor: colors.primary, width: 24 }
67
+ : { backgroundColor: colors.border }
68
+ ]}
69
+ />
70
+ ))}
71
+ </View>
72
+ );
73
+
74
+ // Step container with animations
75
+ const AnimatedStepContainer: React.FC<{
76
+ children: React.ReactNode;
77
+ fadeAnim: Animated.SharedValue<number>;
78
+ slideAnim: Animated.SharedValue<number>;
79
+ scaleAnim: Animated.SharedValue<number>;
80
+ styles: any;
81
+ stepKey: string;
82
+ }> = ({ children, fadeAnim, slideAnim, scaleAnim, styles, stepKey }) => {
83
+ const animatedStyle = useAnimatedStyle(() => ({
84
+ opacity: fadeAnim.value,
85
+ transform: [
86
+ { translateX: slideAnim.value },
87
+ { scale: scaleAnim.value }
88
+ ]
89
+ }));
90
+
91
+ return (
92
+ <Animated.View
93
+ key={stepKey}
94
+ style={[styles.stepContainer, animatedStyle]}
95
+ >
96
+ {children}
97
+ </Animated.View>
98
+ );
99
+ };
100
+
101
+ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
102
+ steps,
103
+ initialStep = 0,
104
+ showProgressIndicator = true,
105
+ enableAnimations = true,
106
+ onStepChange,
107
+ onComplete,
108
+ stepData = [],
109
+ navigate,
110
+ goBack,
111
+ onAuthenticated,
112
+ theme,
113
+ oxyServices,
114
+ }) => {
115
+ const colors = useThemeColors(theme);
116
+ const styles = useMemo(() => ({
117
+ ...createAuthStyles(colors, theme),
118
+ // Additional styles for step components
119
+ modernHeader: {
120
+ alignItems: 'flex-start' as const,
121
+ width: '100%',
122
+ marginBottom: 24,
123
+ },
124
+ modernTitle: {
125
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
126
+ fontWeight: Platform.OS === 'web' ? 'bold' as const : undefined,
127
+ fontSize: 42,
128
+ lineHeight: 50.4, // 42 * 1.2
129
+ marginBottom: 12,
130
+ textAlign: 'left' as const,
131
+ letterSpacing: -0.5,
132
+ },
133
+ modernSubtitle: {
134
+ fontSize: 18,
135
+ lineHeight: 24,
136
+ textAlign: 'left' as const,
137
+ opacity: 0.8,
138
+ },
139
+ modernInputContainer: {
140
+ width: '100%',
141
+ marginBottom: 24,
142
+ },
143
+ button: {
144
+ flexDirection: 'row' as const,
145
+ alignItems: 'center',
146
+ justifyContent: 'center',
147
+ paddingVertical: 18,
148
+ paddingHorizontal: 32,
149
+ borderRadius: 16,
150
+ marginVertical: 8,
151
+ gap: 8,
152
+ width: '100%',
153
+ ...Platform.select({
154
+ web: {
155
+ boxShadow: '0 4px 8px rgba(0,0,0,0.3)',
156
+ },
157
+ default: {
158
+ shadowOffset: { width: 0, height: 4 },
159
+ shadowOpacity: 0.3,
160
+ shadowRadius: 8,
161
+ elevation: 6,
162
+ }
163
+ }),
164
+ },
165
+ buttonText: {
166
+ color: '#FFFFFF',
167
+ fontSize: 16,
168
+ fontWeight: '600' as const,
169
+ letterSpacing: 0.5,
170
+ },
171
+ footerText: {
172
+ fontSize: 14,
173
+ lineHeight: 20,
174
+ },
175
+ footerTextContainer: {
176
+ flexDirection: 'row' as const,
177
+ justifyContent: 'center' as const,
178
+ marginTop: 16,
179
+ },
180
+ linkText: {
181
+ fontSize: 14,
182
+ lineHeight: 20,
183
+ fontWeight: '600' as const,
184
+ textDecorationLine: 'underline' as const,
185
+ },
186
+ }), [colors, theme]);
187
+
188
+ // State management
189
+ const [state, setState] = useState<StepBasedScreenState>({
190
+ currentStep: initialStep,
191
+ stepData: stepData,
192
+ isTransitioning: false,
193
+ });
194
+
195
+ // Update state when stepData prop changes
196
+ useEffect(() => {
197
+ setState(prevState => ({
198
+ ...prevState,
199
+ stepData: stepData,
200
+ }));
201
+ }, [stepData]);
202
+
203
+ // Animation values
204
+ const fadeAnim = useSharedValue(1);
205
+ const slideAnim = useSharedValue(0);
206
+ const scaleAnim = useSharedValue(1);
207
+
208
+ // Refs for animation callbacks
209
+ const onStepChangeRef = useRef(onStepChange);
210
+ const onCompleteRef = useRef(onComplete);
211
+ onStepChangeRef.current = onStepChange;
212
+ onCompleteRef.current = onComplete;
213
+
214
+ // Update step data
215
+ const updateStepData = useCallback((stepIndex: number, data: any) => {
216
+ setState(prev => ({
217
+ ...prev,
218
+ stepData: prev.stepData.map((item, index) =>
219
+ index === stepIndex ? data : item
220
+ ),
221
+ }));
222
+ }, [setState]);
223
+
224
+ // Animation transition function
225
+ const animateTransition = useCallback((nextStep: number) => {
226
+ if (!enableAnimations) {
227
+ setState(prev => ({ ...prev, currentStep: nextStep }));
228
+ onStepChangeRef.current?.(nextStep, steps.length);
229
+ return;
230
+ }
231
+
232
+ setState(prev => ({ ...prev, isTransitioning: true }));
233
+
234
+ // Scale down current content
235
+ scaleAnim.value = withSequence(
236
+ withTiming(0.95, { duration: 150 }),
237
+ withTiming(0.95, { duration: 50 })
238
+ );
239
+
240
+ fadeAnim.value = withSequence(
241
+ withTiming(0, { duration: 200 }),
242
+ withTiming(0, { duration: 50 }, (finished) => {
243
+ if (finished) {
244
+ runOnJS(() => {
245
+ setState(prev => ({
246
+ ...prev,
247
+ currentStep: nextStep,
248
+ isTransitioning: false
249
+ }));
250
+ onStepChangeRef.current?.(nextStep, steps.length);
251
+ })();
252
+
253
+ // Reset animations with proper timing
254
+ slideAnim.value = withDelay(16, withTiming(-50, { duration: 0 }));
255
+ scaleAnim.value = withDelay(16, withTiming(0.95, { duration: 0 }));
256
+
257
+ // Animate in new content
258
+ fadeAnim.value = withDelay(16, withTiming(1, { duration: 300 }));
259
+ slideAnim.value = withDelay(16, withSpring(0, {
260
+ damping: 15,
261
+ stiffness: 200,
262
+ }));
263
+ scaleAnim.value = withDelay(16, withSpring(1, {
264
+ damping: 15,
265
+ stiffness: 200,
266
+ }));
267
+ }
268
+ })
269
+ );
270
+ }, [fadeAnim, slideAnim, scaleAnim, enableAnimations, steps.length]);
271
+
272
+ // Navigation functions
273
+ const nextStep = useCallback(() => {
274
+ if (state.isTransitioning) return;
275
+
276
+ const currentStepConfig = steps[state.currentStep];
277
+ if (currentStepConfig?.canProceed) {
278
+ const stepData = state.stepData[state.currentStep];
279
+ if (!currentStepConfig.canProceed(stepData)) {
280
+ return; // Step validation failed
281
+ }
282
+ }
283
+
284
+ if (state.currentStep < steps.length - 1) {
285
+ // Call onExit for current step
286
+ currentStepConfig?.onExit?.();
287
+
288
+ animateTransition(state.currentStep + 1);
289
+
290
+ // Call onEnter for next step
291
+ const nextStepConfig = steps[state.currentStep + 1];
292
+ nextStepConfig?.onEnter?.();
293
+ } else {
294
+ // Final step - call onComplete
295
+ onCompleteRef.current?.(state.stepData);
296
+ }
297
+ }, [state.currentStep, state.stepData, state.isTransitioning, steps, animateTransition]);
298
+
299
+ const prevStep = useCallback(() => {
300
+ if (state.isTransitioning) return;
301
+
302
+ if (state.currentStep > 0) {
303
+ // Call onExit for current step
304
+ const currentStepConfig = steps[state.currentStep];
305
+ currentStepConfig?.onExit?.();
306
+
307
+ animateTransition(state.currentStep - 1);
308
+
309
+ // Call onEnter for previous step
310
+ const prevStepConfig = steps[state.currentStep - 1];
311
+ prevStepConfig?.onEnter?.();
312
+ } else {
313
+ // First step - go back
314
+ goBack?.();
315
+ }
316
+ }, [state.currentStep, state.isTransitioning, steps, animateTransition, goBack]);
317
+
318
+ const goToStep = useCallback((stepIndex: number) => {
319
+ if (state.isTransitioning || stepIndex < 0 || stepIndex >= steps.length) return;
320
+
321
+ if (stepIndex !== state.currentStep) {
322
+ // Call onExit for current step
323
+ const currentStepConfig = steps[state.currentStep];
324
+ currentStepConfig?.onExit?.();
325
+
326
+ animateTransition(stepIndex);
327
+
328
+ // Call onEnter for target step
329
+ const targetStepConfig = steps[stepIndex];
330
+ targetStepConfig?.onEnter?.();
331
+ }
332
+ }, [state.currentStep, state.isTransitioning, steps, animateTransition]);
333
+
334
+ // Get current step component
335
+ const currentStepConfig = steps[state.currentStep];
336
+ const CurrentStepComponent = currentStepConfig?.component;
337
+
338
+ // Enhanced props for the step component
339
+ const stepProps = {
340
+ ...currentStepConfig?.props,
341
+ // Common props
342
+ colors,
343
+ styles,
344
+ theme,
345
+ navigate,
346
+ goBack,
347
+ onAuthenticated,
348
+ oxyServices,
349
+
350
+ // Step navigation
351
+ nextStep,
352
+ prevStep,
353
+ goToStep,
354
+ currentStep: state.currentStep,
355
+ totalSteps: steps.length,
356
+
357
+ // Step data - spread the step data properties directly as props
358
+ ...state.stepData[state.currentStep],
359
+
360
+ // Step data management
361
+ updateStepData: (data: any) => updateStepData(state.currentStep, data),
362
+ allStepData: state.stepData,
363
+
364
+ // State
365
+ isTransitioning: state.isTransitioning,
366
+
367
+ // Animation refs (for components that need direct access)
368
+ fadeAnim,
369
+ slideAnim,
370
+ scaleAnim,
371
+ };
372
+
373
+ return (
374
+ <KeyboardAvoidingView
375
+ style={[styles.container, { backgroundColor: colors.background }]}
376
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
377
+ >
378
+ <StatusBar
379
+ barStyle={theme === 'dark' ? 'light-content' : 'dark-content'}
380
+ backgroundColor={colors.background}
381
+ />
382
+
383
+ <ScrollView
384
+ contentContainerStyle={styles.scrollContent}
385
+ showsVerticalScrollIndicator={false}
386
+ keyboardShouldPersistTaps="handled"
387
+ bounces={false}
388
+ alwaysBounceVertical={false}
389
+ overScrollMode="never"
390
+ removeClippedSubviews={true}
391
+ >
392
+ {showProgressIndicator && steps.length > 1 && (
393
+ <ProgressIndicator
394
+ currentStep={state.currentStep}
395
+ totalSteps={steps.length}
396
+ colors={colors}
397
+ styles={styles}
398
+ />
399
+ )}
400
+
401
+ <AnimatedStepContainer
402
+ fadeAnim={fadeAnim}
403
+ slideAnim={slideAnim}
404
+ scaleAnim={scaleAnim}
405
+ styles={styles}
406
+ stepKey={`step-${state.currentStep}`}
407
+ >
408
+ {CurrentStepComponent && (
409
+ <CurrentStepComponent {...stepProps} />
410
+ )}
411
+ </AnimatedStepContainer>
412
+ </ScrollView>
413
+ </KeyboardAvoidingView>
414
+ );
415
+ };
416
+
417
+ export default StepBasedScreen;
@@ -1,10 +1,10 @@
1
1
  import type React from 'react';
2
- import { View, StyleSheet } from 'react-native';
2
+ import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
3
3
  import Svg, { G, Path } from 'react-native-svg';
4
4
 
5
5
  interface FAIRWalletIconProps {
6
6
  size?: number;
7
- style?: any;
7
+ style?: StyleProp<ViewStyle>;
8
8
  }
9
9
 
10
10
  const FAIRWalletIcon: React.FC<FAIRWalletIconProps> = ({ size = 28, style }) => {
@@ -1,26 +1,25 @@
1
1
  import type React from 'react';
2
- import { Platform } from 'react-native';
2
+ import { Platform, type StyleProp, type TextStyle } from 'react-native';
3
3
  import { Ionicons } from '@expo/vector-icons';
4
4
 
5
5
  export interface IconProps {
6
6
  name: string;
7
7
  size?: number;
8
8
  color?: string;
9
- style?: any;
9
+ style?: Record<string, unknown>;
10
10
  }
11
11
 
12
- const OxyIcon: React.FC<IconProps> = ({
13
- name,
14
- size = 24,
15
- color = '#000',
16
- style
12
+ const OxyIcon: React.FC<IconProps> = ({
13
+ name,
14
+ size = 24,
15
+ color = '#000',
16
+ style
17
17
  }) => {
18
- // Handle both string and Ionicons name types
19
- const iconName = name as any;
20
-
18
+ // Icon name is already properly typed as IoniconsGlyphs
19
+
21
20
  return (
22
21
  <Ionicons
23
- name={iconName}
22
+ name={name as any}
24
23
  size={size}
25
24
  color={color}
26
25
  style={style}
@@ -1,6 +1,15 @@
1
1
  import type React from 'react';
2
2
  import { useRef } from 'react';
3
- import { View, TextInput, StyleSheet, Platform } from 'react-native';
3
+ import { View, TextInput, StyleSheet, Platform, type NativeSyntheticEvent, type TextInputKeyPressEventData } from 'react-native';
4
+
5
+ interface PinInputColors {
6
+ primary: string;
7
+ secondary?: string;
8
+ background: string;
9
+ inputBackground: string;
10
+ text: string;
11
+ border: string;
12
+ }
4
13
 
5
14
  interface PinInputProps {
6
15
  value: string;
@@ -8,7 +17,7 @@ interface PinInputProps {
8
17
  length?: number;
9
18
  disabled?: boolean;
10
19
  autoFocus?: boolean;
11
- colors: any;
20
+ colors: PinInputColors;
12
21
  }
13
22
 
14
23
  const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabled, autoFocus, colors }) => {
@@ -34,7 +43,7 @@ const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabl
34
43
  }
35
44
  };
36
45
 
37
- const handleKeyPress = (e: any, idx: number) => {
46
+ const handleKeyPress = (e: NativeSyntheticEvent<TextInputKeyPressEventData>, idx: number) => {
38
47
  if (e.nativeEvent.key === 'Backspace' && !value[idx] && idx > 0) {
39
48
  inputs.current[idx - 1]?.focus();
40
49
  }
@@ -44,7 +53,7 @@ const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabl
44
53
  <View style={styles.pinContainer}>
45
54
  {Array.from({ length }).map((_, idx) => (
46
55
  <TextInput
47
- key={idx}
56
+ key={`pin-input-${idx}`}
48
57
  ref={(ref) => { inputs.current[idx] = ref; }}
49
58
  style={[
50
59
  styles.pinInput,
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useState, useCallback } from 'react';
2
- import { View, Text, LayoutChangeEvent } from 'react-native';
2
+ import { View, Text, type LayoutChangeEvent } from 'react-native';
3
3
  import type { FileMetadata } from '../../../models/interfaces';
4
4
  // Using plain React Native styles (nativewind not installed in this repo)
5
5
 
@@ -1,4 +1,5 @@
1
- import React, { createContext, useContext, useEffect, useCallback, type ReactNode, useMemo, useRef, useState } from 'react';
1
+ import type React from 'react';
2
+ import { createContext, useContext, useEffect, useCallback, useMemo, useRef, useState, type ReactNode } from 'react';
2
3
  import type { UseFollowHook } from '../hooks/useFollow.types';
3
4
  import { View, Text } from 'react-native';
4
5
  import { OxyServices } from '../../core';
@@ -167,13 +168,13 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
167
168
  const logoutStore = useAuthStore((state) => state.logout);
168
169
 
169
170
  // Local state for non-auth fields
170
- const [minimalUser, setMinimalUser] = React.useState<MinimalUserData | null>(null);
171
- const [sessions, setSessions] = React.useState<ClientSession[]>([]);
172
- const [activeSessionId, setActiveSessionId] = React.useState<string | null>(null);
173
- const [storage, setStorage] = React.useState<StorageInterface | null>(null);
174
- const [currentLanguage, setCurrentLanguage] = React.useState<string>('en');
171
+ const [minimalUser, setMinimalUser] = useState<MinimalUserData | null>(null);
172
+ const [sessions, setSessions] = useState<ClientSession[]>([]);
173
+ const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
174
+ const [storage, setStorage] = useState<StorageInterface | null>(null);
175
+ const [currentLanguage, setCurrentLanguage] = useState<string>('en');
175
176
  // Add a new state to track token restoration
176
- const [tokenReady, setTokenReady] = React.useState(false);
177
+ const [tokenReady, setTokenReady] = useState(false);
177
178
 
178
179
  // Storage keys (memoized to prevent infinite loops)
179
180
  const keys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
@@ -209,7 +210,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
209
210
  useAuthStore.setState({ isLoading: true });
210
211
  try {
211
212
  setTokenReady(false);
212
-
213
+
213
214
  // Load saved language preference
214
215
  const savedLanguage = await storage.getItem(keys.language);
215
216
  if (savedLanguage) {
@@ -626,12 +627,12 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
626
627
  // Save language preference
627
628
  await storage.setItem(keys.language, languageId);
628
629
  setCurrentLanguage(languageId);
629
-
630
+
630
631
  console.log(`Language changed to ${languageId}`);
631
-
632
+
632
633
  // TODO: Here you can add any additional logic needed for app-wide language updates
633
634
  // such as updating i18n configuration, refreshing translations, etc.
634
-
635
+
635
636
  } catch (error) {
636
637
  console.error('Error saving language preference:', error);
637
638
  throw error;
@@ -58,9 +58,9 @@ export type PaymentItem = {
58
58
  };
59
59
 
60
60
  // Extend props to accept onPaymentResult, amount, and currency
61
- interface PaymentGatewayResult {
61
+ export interface PaymentGatewayResult {
62
62
  success: boolean;
63
- details?: any;
63
+ details?: Record<string, string | number | boolean | null>;
64
64
  error?: string;
65
65
  }
66
66