@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.
- package/lib/commonjs/ui/components/AnimationExample.js +1 -1
- package/lib/commonjs/ui/components/AnimationExample.js.map +1 -1
- package/lib/commonjs/ui/components/Header.js +2 -2
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.README.md +337 -0
- package/lib/commonjs/ui/components/StepBasedScreen.js +361 -0
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -0
- package/lib/commonjs/ui/components/icon/OxyIcon.js +3 -3
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +7 -7
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +55 -55
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +87 -219
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +138 -235
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +139 -742
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +3 -3
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +2 -2
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +110 -0
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +138 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +141 -0
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +165 -0
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +150 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +171 -0
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +163 -0
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +170 -0
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +72 -0
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
- package/lib/module/ui/components/AnimationExample.js +1 -1
- package/lib/module/ui/components/AnimationExample.js.map +1 -1
- package/lib/module/ui/components/Header.js +2 -2
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/Section.js.map +1 -1
- package/lib/module/ui/components/SectionTitle.js.map +1 -1
- package/lib/module/ui/components/StepBasedScreen.README.md +337 -0
- package/lib/module/ui/components/StepBasedScreen.js +356 -0
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -0
- package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/module/ui/components/icon/OxyIcon.js +3 -3
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +1 -1
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +7 -7
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +55 -55
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +91 -222
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +140 -237
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +141 -743
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +3 -3
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +2 -2
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +105 -0
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +133 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +136 -0
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +160 -0
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +145 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +166 -0
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +158 -0
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +165 -0
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +67 -0
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
- package/lib/typescript/models/interfaces.d.ts +4 -3
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/ui/components/AnimationExample.d.ts +1 -1
- package/lib/typescript/ui/components/AnimationExample.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyPayButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/Section.d.ts +2 -1
- package/lib/typescript/ui/components/Section.d.ts.map +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts +2 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts +24 -0
- package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -0
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +2 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +9 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +2 -1
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +2 -9
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +21 -0
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +18 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +24 -0
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +27 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +27 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +25 -0
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +26 -0
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +16 -0
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +13 -0
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -0
- package/package.json +2 -3
- package/src/models/interfaces.ts +5 -3
- package/src/ui/components/AnimationExample.tsx +9 -8
- package/src/ui/components/Header.tsx +2 -2
- package/src/ui/components/OxyPayButton.tsx +2 -2
- package/src/ui/components/OxyProvider.tsx +1 -1
- package/src/ui/components/Section.tsx +7 -7
- package/src/ui/components/SectionTitle.tsx +2 -2
- package/src/ui/components/StepBasedScreen.README.md +337 -0
- package/src/ui/components/StepBasedScreen.tsx +417 -0
- package/src/ui/components/icon/FAIRWalletIcon.tsx +2 -2
- package/src/ui/components/icon/OxyIcon.tsx +10 -11
- package/src/ui/components/internal/PinInput.tsx +13 -4
- package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +1 -1
- package/src/ui/context/OxyContext.tsx +12 -11
- package/src/ui/screens/PaymentGatewayScreen.tsx +2 -2
- package/src/ui/screens/ProfileScreen.tsx +54 -54
- package/src/ui/screens/RecoverAccountScreen.tsx +98 -211
- package/src/ui/screens/SignInScreen.tsx +148 -271
- package/src/ui/screens/SignUpScreen.tsx +146 -748
- package/src/ui/screens/internal/SignInPasswordStep.tsx +3 -3
- package/src/ui/screens/internal/SignInUsernameStep.tsx +2 -2
- package/src/ui/screens/steps/RecoverRequestStep.tsx +130 -0
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +131 -0
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +153 -0
- package/src/ui/screens/steps/SignInPasswordStep.tsx +172 -0
- package/src/ui/screens/steps/SignInUsernameStep.tsx +176 -0
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +204 -0
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +191 -0
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +130 -0
- 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?:
|
|
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?:
|
|
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
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
// Icon name is already properly typed as IoniconsGlyphs
|
|
19
|
+
|
|
21
20
|
return (
|
|
22
21
|
<Ionicons
|
|
23
|
-
name={
|
|
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:
|
|
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:
|
|
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
|
|
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] =
|
|
171
|
-
const [sessions, setSessions] =
|
|
172
|
-
const [activeSessionId, setActiveSessionId] =
|
|
173
|
-
const [storage, setStorage] =
|
|
174
|
-
const [currentLanguage, setCurrentLanguage] =
|
|
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] =
|
|
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?:
|
|
63
|
+
details?: Record<string, string | number | boolean | null>;
|
|
64
64
|
error?: string;
|
|
65
65
|
}
|
|
66
66
|
|