@oxyhq/services 5.11.10 → 5.11.12
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/FollowButton.js +1 -1
- package/lib/commonjs/ui/components/FollowButton.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 +3 -3
- 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/PaymentGatewayScreen.js +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.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/FollowButton.js +1 -1
- package/lib/module/ui/components/FollowButton.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 +3 -3
- 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/PaymentGatewayScreen.js +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.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/FollowButton.tsx +2 -2
- package/src/ui/components/Header.tsx +2 -2
- package/src/ui/components/OxyPayButton.tsx +2 -2
- package/src/ui/components/OxyProvider.tsx +4 -4
- 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 +3 -3
- 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
|
@@ -57,7 +57,7 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
|
|
|
57
57
|
}) => {
|
|
58
58
|
const inputRef = useRef<TextInput>(null);
|
|
59
59
|
|
|
60
|
-
// Animated styles
|
|
60
|
+
// Animated styles - properly memoized to prevent re-renders
|
|
61
61
|
const containerAnimatedStyle = useAnimatedStyle(() => {
|
|
62
62
|
return {
|
|
63
63
|
opacity: fadeAnim.value,
|
|
@@ -66,13 +66,13 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
|
|
|
66
66
|
{ scale: scaleAnim.value }
|
|
67
67
|
]
|
|
68
68
|
};
|
|
69
|
-
}
|
|
69
|
+
});
|
|
70
70
|
|
|
71
71
|
const logoAnimatedStyle = useAnimatedStyle(() => {
|
|
72
72
|
return {
|
|
73
73
|
transform: [{ scale: logoAnim.value }]
|
|
74
74
|
};
|
|
75
|
-
}
|
|
75
|
+
});
|
|
76
76
|
|
|
77
77
|
// Focus password input on error or when step becomes active
|
|
78
78
|
useEffect(() => {
|
|
@@ -53,7 +53,7 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
|
|
|
53
53
|
}) => {
|
|
54
54
|
const inputRef = useRef<TextInput>(null);
|
|
55
55
|
|
|
56
|
-
// Animated styles
|
|
56
|
+
// Animated styles - properly memoized to prevent re-renders
|
|
57
57
|
const animatedStyle = useAnimatedStyle(() => {
|
|
58
58
|
return {
|
|
59
59
|
opacity: fadeAnim.value,
|
|
@@ -62,7 +62,7 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
|
|
|
62
62
|
{ scale: scaleAnim.value }
|
|
63
63
|
]
|
|
64
64
|
};
|
|
65
|
-
}
|
|
65
|
+
});
|
|
66
66
|
|
|
67
67
|
const handleUsernameContinue = () => {
|
|
68
68
|
if (!username || validationStatus === 'invalid') {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { View, Text } from 'react-native';
|
|
4
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
5
|
+
import HighFive from '../../../assets/illustrations/HighFive';
|
|
6
|
+
import TextField from '../../components/internal/TextField';
|
|
7
|
+
import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
|
|
8
|
+
|
|
9
|
+
interface RecoverRequestStepProps {
|
|
10
|
+
// Common props from StepBasedScreen
|
|
11
|
+
colors: any;
|
|
12
|
+
styles: any;
|
|
13
|
+
theme: string;
|
|
14
|
+
navigate: (screen: string, props?: Record<string, any>) => void;
|
|
15
|
+
|
|
16
|
+
// Step navigation
|
|
17
|
+
nextStep: () => void;
|
|
18
|
+
currentStep: number;
|
|
19
|
+
totalSteps: number;
|
|
20
|
+
|
|
21
|
+
// Data management
|
|
22
|
+
stepData?: any;
|
|
23
|
+
updateStepData: (data: any) => void;
|
|
24
|
+
|
|
25
|
+
// Form state
|
|
26
|
+
identifier: string;
|
|
27
|
+
setIdentifier: (identifier: string) => void;
|
|
28
|
+
errorMessage: string;
|
|
29
|
+
setErrorMessage: (message: string) => void;
|
|
30
|
+
isLoading: boolean;
|
|
31
|
+
setIsLoading: (loading: boolean) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const RecoverRequestStep: React.FC<RecoverRequestStepProps> = ({
|
|
35
|
+
colors,
|
|
36
|
+
styles,
|
|
37
|
+
navigate,
|
|
38
|
+
nextStep,
|
|
39
|
+
identifier,
|
|
40
|
+
setIdentifier,
|
|
41
|
+
errorMessage,
|
|
42
|
+
setErrorMessage,
|
|
43
|
+
isLoading,
|
|
44
|
+
setIsLoading,
|
|
45
|
+
}) => {
|
|
46
|
+
const inputRef = useRef<any>(null);
|
|
47
|
+
|
|
48
|
+
const handleIdentifierChange = (text: string) => {
|
|
49
|
+
setIdentifier(text);
|
|
50
|
+
if (errorMessage) setErrorMessage('');
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleRequest = () => {
|
|
54
|
+
if (!identifier || identifier.length < 3) {
|
|
55
|
+
setErrorMessage('Please enter your email or username.');
|
|
56
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setErrorMessage('');
|
|
61
|
+
setIsLoading(true);
|
|
62
|
+
|
|
63
|
+
// Simulate API call
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
setIsLoading(false);
|
|
66
|
+
nextStep(); // Move to verification step
|
|
67
|
+
}, 1200);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleRequestWithFocus = () => {
|
|
71
|
+
if (!identifier) {
|
|
72
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
73
|
+
}
|
|
74
|
+
handleRequest();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<>
|
|
79
|
+
<HighFive width={100} height={100} />
|
|
80
|
+
<View style={styles.modernHeader}>
|
|
81
|
+
<Text style={[styles.modernTitle, { color: colors.text }]}>
|
|
82
|
+
Recover Account
|
|
83
|
+
</Text>
|
|
84
|
+
<Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
|
|
85
|
+
Enter your email or username to receive a 6-digit code.
|
|
86
|
+
</Text>
|
|
87
|
+
</View>
|
|
88
|
+
|
|
89
|
+
<View style={styles.modernInputContainer}>
|
|
90
|
+
<TextField
|
|
91
|
+
ref={inputRef}
|
|
92
|
+
label="Email or Username"
|
|
93
|
+
leading={<Ionicons name="mail-outline" size={24} color={colors.secondaryText} />}
|
|
94
|
+
value={identifier}
|
|
95
|
+
onChangeText={handleIdentifierChange}
|
|
96
|
+
autoCapitalize="none"
|
|
97
|
+
autoCorrect={false}
|
|
98
|
+
testID="recover-identifier-input"
|
|
99
|
+
variant="filled"
|
|
100
|
+
error={errorMessage || undefined}
|
|
101
|
+
editable={!isLoading}
|
|
102
|
+
onSubmitEditing={handleRequestWithFocus}
|
|
103
|
+
autoFocus
|
|
104
|
+
/>
|
|
105
|
+
</View>
|
|
106
|
+
|
|
107
|
+
<GroupedPillButtons
|
|
108
|
+
buttons={[
|
|
109
|
+
{
|
|
110
|
+
text: 'Back to Sign In',
|
|
111
|
+
onPress: () => navigate('SignIn'),
|
|
112
|
+
icon: 'arrow-back',
|
|
113
|
+
variant: 'transparent',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
text: 'Send Code',
|
|
117
|
+
onPress: handleRequest,
|
|
118
|
+
icon: 'mail-open-outline',
|
|
119
|
+
variant: 'primary',
|
|
120
|
+
loading: isLoading,
|
|
121
|
+
disabled: isLoading,
|
|
122
|
+
},
|
|
123
|
+
]}
|
|
124
|
+
colors={colors}
|
|
125
|
+
/>
|
|
126
|
+
</>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default RecoverRequestStep;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { View, Text } from 'react-native';
|
|
3
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
4
|
+
import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
|
|
5
|
+
|
|
6
|
+
interface RecoverSuccessStepProps {
|
|
7
|
+
// Common props from StepBasedScreen
|
|
8
|
+
colors: any;
|
|
9
|
+
styles: any;
|
|
10
|
+
theme: string;
|
|
11
|
+
navigate: (screen: string, props?: Record<string, any>) => void;
|
|
12
|
+
|
|
13
|
+
// Step navigation
|
|
14
|
+
nextStep: () => void;
|
|
15
|
+
prevStep: () => void;
|
|
16
|
+
currentStep: number;
|
|
17
|
+
totalSteps: number;
|
|
18
|
+
|
|
19
|
+
// Data management
|
|
20
|
+
stepData?: any;
|
|
21
|
+
updateStepData: (data: any) => void;
|
|
22
|
+
allStepData: any[];
|
|
23
|
+
|
|
24
|
+
// Form state
|
|
25
|
+
successMessage: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const RecoverSuccessStep: React.FC<RecoverSuccessStepProps> = ({
|
|
29
|
+
colors,
|
|
30
|
+
styles,
|
|
31
|
+
navigate,
|
|
32
|
+
allStepData,
|
|
33
|
+
successMessage,
|
|
34
|
+
}) => {
|
|
35
|
+
// Extract identifier from previous steps
|
|
36
|
+
const requestData = allStepData[0] || {};
|
|
37
|
+
const { identifier } = requestData;
|
|
38
|
+
|
|
39
|
+
const handleContinueToReset = () => {
|
|
40
|
+
// Navigate to password reset with the identifier
|
|
41
|
+
navigate('ResetPassword', { identifier });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleBackToSignIn = () => {
|
|
45
|
+
navigate('SignIn');
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<>
|
|
50
|
+
<View style={{
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
justifyContent: 'center',
|
|
53
|
+
marginBottom: 32,
|
|
54
|
+
}}>
|
|
55
|
+
<View style={{
|
|
56
|
+
width: 80,
|
|
57
|
+
height: 80,
|
|
58
|
+
borderRadius: 40,
|
|
59
|
+
backgroundColor: colors.success + '20',
|
|
60
|
+
alignItems: 'center',
|
|
61
|
+
justifyContent: 'center',
|
|
62
|
+
marginBottom: 24,
|
|
63
|
+
}}>
|
|
64
|
+
<Ionicons name="checkmark-circle" size={40} color={colors.success} />
|
|
65
|
+
</View>
|
|
66
|
+
</View>
|
|
67
|
+
|
|
68
|
+
<View style={styles.modernHeader}>
|
|
69
|
+
<Text style={[styles.modernTitle, { color: colors.text }]}>
|
|
70
|
+
Account Verified!
|
|
71
|
+
</Text>
|
|
72
|
+
<Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
|
|
73
|
+
Your account has been successfully verified.
|
|
74
|
+
</Text>
|
|
75
|
+
</View>
|
|
76
|
+
|
|
77
|
+
<View style={styles.modernInputContainer}>
|
|
78
|
+
<View style={{
|
|
79
|
+
padding: 20,
|
|
80
|
+
backgroundColor: colors.inputBackground,
|
|
81
|
+
borderRadius: 16,
|
|
82
|
+
borderWidth: 1,
|
|
83
|
+
borderColor: colors.border,
|
|
84
|
+
marginBottom: 24,
|
|
85
|
+
}}>
|
|
86
|
+
<Text style={[styles.footerText, { color: colors.text, fontSize: 16, marginBottom: 8 }]}>
|
|
87
|
+
What's next?
|
|
88
|
+
</Text>
|
|
89
|
+
<Text style={[styles.footerText, { color: colors.secondaryText, fontSize: 14, lineHeight: 20 }]}>
|
|
90
|
+
You can now reset your password or return to sign in with your existing credentials.
|
|
91
|
+
</Text>
|
|
92
|
+
</View>
|
|
93
|
+
|
|
94
|
+
<View style={{
|
|
95
|
+
flexDirection: 'row',
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
padding: 12,
|
|
98
|
+
backgroundColor: colors.success + '10',
|
|
99
|
+
borderRadius: 8,
|
|
100
|
+
borderWidth: 1,
|
|
101
|
+
borderColor: colors.success + '30',
|
|
102
|
+
}}>
|
|
103
|
+
<Ionicons name="shield-checkmark" size={20} color={colors.success} style={{ marginRight: 8 }} />
|
|
104
|
+
<Text style={[styles.footerText, { color: colors.success, fontSize: 14, flex: 1 }]}>
|
|
105
|
+
{successMessage || 'Your account recovery is complete and secure.'}
|
|
106
|
+
</Text>
|
|
107
|
+
</View>
|
|
108
|
+
</View>
|
|
109
|
+
|
|
110
|
+
<GroupedPillButtons
|
|
111
|
+
buttons={[
|
|
112
|
+
{
|
|
113
|
+
text: 'Back to Sign In',
|
|
114
|
+
onPress: handleBackToSignIn,
|
|
115
|
+
icon: 'arrow-back',
|
|
116
|
+
variant: 'transparent',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
text: 'Reset Password',
|
|
120
|
+
onPress: handleContinueToReset,
|
|
121
|
+
icon: 'key-outline',
|
|
122
|
+
variant: 'primary',
|
|
123
|
+
},
|
|
124
|
+
]}
|
|
125
|
+
colors={colors}
|
|
126
|
+
/>
|
|
127
|
+
</>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export default RecoverSuccessStep;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { View, Text } from 'react-native';
|
|
3
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
4
|
+
import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
|
|
5
|
+
import PinInput from '../../components/internal/PinInput';
|
|
6
|
+
|
|
7
|
+
interface RecoverVerifyStepProps {
|
|
8
|
+
// Common props from StepBasedScreen
|
|
9
|
+
colors: any;
|
|
10
|
+
styles: any;
|
|
11
|
+
theme: string;
|
|
12
|
+
navigate: (screen: string, props?: Record<string, any>) => void;
|
|
13
|
+
|
|
14
|
+
// Step navigation
|
|
15
|
+
nextStep: () => void;
|
|
16
|
+
prevStep: () => void;
|
|
17
|
+
currentStep: number;
|
|
18
|
+
totalSteps: number;
|
|
19
|
+
|
|
20
|
+
// Data management
|
|
21
|
+
stepData?: any;
|
|
22
|
+
updateStepData: (data: any) => void;
|
|
23
|
+
|
|
24
|
+
// Form state
|
|
25
|
+
verificationCode: string;
|
|
26
|
+
setVerificationCode: (code: string) => void;
|
|
27
|
+
errorMessage: string;
|
|
28
|
+
setErrorMessage: (message: string) => void;
|
|
29
|
+
successMessage: string;
|
|
30
|
+
setSuccessMessage: (message: string) => void;
|
|
31
|
+
isLoading: boolean;
|
|
32
|
+
setIsLoading: (loading: boolean) => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const RecoverVerifyStep: React.FC<RecoverVerifyStepProps> = ({
|
|
36
|
+
colors,
|
|
37
|
+
styles,
|
|
38
|
+
nextStep,
|
|
39
|
+
prevStep,
|
|
40
|
+
verificationCode,
|
|
41
|
+
setVerificationCode,
|
|
42
|
+
errorMessage,
|
|
43
|
+
setErrorMessage,
|
|
44
|
+
successMessage,
|
|
45
|
+
setSuccessMessage,
|
|
46
|
+
isLoading,
|
|
47
|
+
setIsLoading,
|
|
48
|
+
}) => {
|
|
49
|
+
const handleVerifyCode = () => {
|
|
50
|
+
setErrorMessage('');
|
|
51
|
+
setSuccessMessage('');
|
|
52
|
+
|
|
53
|
+
if (verificationCode.length !== 6) {
|
|
54
|
+
setErrorMessage('Please enter the 6-digit code.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setIsLoading(true);
|
|
59
|
+
|
|
60
|
+
// Simulate verification
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
if (verificationCode === '123456') { // Simulate correct code
|
|
64
|
+
setSuccessMessage('Your account has been verified! You can now reset your password.');
|
|
65
|
+
nextStep(); // Move to success step
|
|
66
|
+
} else {
|
|
67
|
+
setErrorMessage('Invalid code. Please try again.');
|
|
68
|
+
}
|
|
69
|
+
}, 1200);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<View style={styles.modernHeader}>
|
|
75
|
+
<Text style={[styles.modernTitle, { color: colors.text }]}>
|
|
76
|
+
Verify Code
|
|
77
|
+
</Text>
|
|
78
|
+
<Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
|
|
79
|
+
Enter the 6-digit code sent to your email or phone.
|
|
80
|
+
</Text>
|
|
81
|
+
</View>
|
|
82
|
+
|
|
83
|
+
<View style={styles.modernInputContainer}>
|
|
84
|
+
<PinInput
|
|
85
|
+
value={verificationCode}
|
|
86
|
+
onChange={setVerificationCode}
|
|
87
|
+
length={6}
|
|
88
|
+
disabled={isLoading}
|
|
89
|
+
autoFocus
|
|
90
|
+
colors={colors}
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
{successMessage && (
|
|
94
|
+
<View style={{
|
|
95
|
+
flexDirection: 'row',
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
marginTop: 16,
|
|
98
|
+
padding: 12,
|
|
99
|
+
backgroundColor: colors.success + '10',
|
|
100
|
+
borderRadius: 8,
|
|
101
|
+
borderWidth: 1,
|
|
102
|
+
borderColor: colors.success + '30',
|
|
103
|
+
}}>
|
|
104
|
+
<Ionicons name="checkmark-circle" size={20} color={colors.success} style={{ marginRight: 8 }} />
|
|
105
|
+
<Text style={[styles.footerText, { color: colors.success, fontSize: 14 }]}>
|
|
106
|
+
{successMessage}
|
|
107
|
+
</Text>
|
|
108
|
+
</View>
|
|
109
|
+
)}
|
|
110
|
+
|
|
111
|
+
{errorMessage && (
|
|
112
|
+
<View style={{
|
|
113
|
+
flexDirection: 'row',
|
|
114
|
+
alignItems: 'center',
|
|
115
|
+
marginTop: 16,
|
|
116
|
+
padding: 12,
|
|
117
|
+
backgroundColor: colors.error + '10',
|
|
118
|
+
borderRadius: 8,
|
|
119
|
+
borderWidth: 1,
|
|
120
|
+
borderColor: colors.error + '30',
|
|
121
|
+
}}>
|
|
122
|
+
<Ionicons name="alert-circle" size={20} color={colors.error} style={{ marginRight: 8 }} />
|
|
123
|
+
<Text style={[styles.footerText, { color: colors.error, fontSize: 14 }]}>
|
|
124
|
+
{errorMessage}
|
|
125
|
+
</Text>
|
|
126
|
+
</View>
|
|
127
|
+
)}
|
|
128
|
+
</View>
|
|
129
|
+
|
|
130
|
+
<GroupedPillButtons
|
|
131
|
+
buttons={[
|
|
132
|
+
{
|
|
133
|
+
text: 'Back',
|
|
134
|
+
onPress: prevStep,
|
|
135
|
+
icon: 'arrow-back',
|
|
136
|
+
variant: 'transparent',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
text: 'Verify Code',
|
|
140
|
+
onPress: handleVerifyCode,
|
|
141
|
+
icon: 'checkmark-circle-outline',
|
|
142
|
+
variant: 'primary',
|
|
143
|
+
loading: isLoading,
|
|
144
|
+
disabled: isLoading || verificationCode.length !== 6,
|
|
145
|
+
},
|
|
146
|
+
]}
|
|
147
|
+
colors={colors}
|
|
148
|
+
/>
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default RecoverVerifyStep;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
import { View, Text, TouchableOpacity } from 'react-native';
|
|
4
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
5
|
+
import Avatar from '../../components/Avatar';
|
|
6
|
+
import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
|
|
7
|
+
import TextField from '../../components/internal/TextField';
|
|
8
|
+
|
|
9
|
+
interface SignInPasswordStepProps {
|
|
10
|
+
// Common props from StepBasedScreen
|
|
11
|
+
colors: any;
|
|
12
|
+
styles: any;
|
|
13
|
+
theme: string;
|
|
14
|
+
navigate: (screen: string, props?: Record<string, any>) => void;
|
|
15
|
+
|
|
16
|
+
// Step navigation
|
|
17
|
+
nextStep: () => void;
|
|
18
|
+
prevStep: () => void;
|
|
19
|
+
currentStep: number;
|
|
20
|
+
totalSteps: number;
|
|
21
|
+
|
|
22
|
+
// Data management
|
|
23
|
+
stepData?: any;
|
|
24
|
+
updateStepData: (data: any) => void;
|
|
25
|
+
allStepData: any[];
|
|
26
|
+
|
|
27
|
+
// Form state
|
|
28
|
+
password: string;
|
|
29
|
+
setPassword: (password: string) => void;
|
|
30
|
+
showPassword: boolean;
|
|
31
|
+
setShowPassword: (show: boolean) => void;
|
|
32
|
+
errorMessage: string;
|
|
33
|
+
setErrorMessage: (message: string) => void;
|
|
34
|
+
isLoading: boolean;
|
|
35
|
+
|
|
36
|
+
// User profile
|
|
37
|
+
userProfile: any;
|
|
38
|
+
username: string;
|
|
39
|
+
|
|
40
|
+
// Sign-in function
|
|
41
|
+
handleSignIn: () => Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
|
|
45
|
+
colors,
|
|
46
|
+
styles,
|
|
47
|
+
theme,
|
|
48
|
+
navigate,
|
|
49
|
+
prevStep,
|
|
50
|
+
password,
|
|
51
|
+
setPassword,
|
|
52
|
+
showPassword,
|
|
53
|
+
setShowPassword,
|
|
54
|
+
errorMessage,
|
|
55
|
+
setErrorMessage,
|
|
56
|
+
isLoading,
|
|
57
|
+
userProfile,
|
|
58
|
+
username,
|
|
59
|
+
handleSignIn,
|
|
60
|
+
}) => {
|
|
61
|
+
const inputRef = useRef<any>(null);
|
|
62
|
+
|
|
63
|
+
const handlePasswordChange = (text: string) => {
|
|
64
|
+
setPassword(text);
|
|
65
|
+
if (errorMessage) setErrorMessage('');
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const handleSignInSubmit = async () => {
|
|
69
|
+
if (!password) {
|
|
70
|
+
setErrorMessage('Please enter your password.');
|
|
71
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Call the actual sign-in function passed from props
|
|
76
|
+
await handleSignIn();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const togglePasswordVisibility = () => {
|
|
80
|
+
setShowPassword(!showPassword);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Focus password input on error
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (errorMessage) {
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
inputRef.current?.focus();
|
|
88
|
+
}, 0);
|
|
89
|
+
}
|
|
90
|
+
}, [errorMessage]);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<>
|
|
94
|
+
<View style={styles.modernUserProfileContainer}>
|
|
95
|
+
<View style={styles.avatarContainer}>
|
|
96
|
+
<Avatar
|
|
97
|
+
name={userProfile?.displayName || userProfile?.name || username}
|
|
98
|
+
size={100}
|
|
99
|
+
theme={theme as 'light' | 'dark'}
|
|
100
|
+
style={styles.modernUserAvatar}
|
|
101
|
+
backgroundColor={colors.primary + '20'}
|
|
102
|
+
/>
|
|
103
|
+
<View style={[styles.statusIndicator, { backgroundColor: colors.primary }]} />
|
|
104
|
+
</View>
|
|
105
|
+
<Text style={[styles.modernUserDisplayName, { color: colors.text }]}>
|
|
106
|
+
{userProfile?.displayName || userProfile?.name || username}
|
|
107
|
+
</Text>
|
|
108
|
+
<Text style={[styles.modernUsernameSubtext, { color: colors.secondaryText }]}>
|
|
109
|
+
@{username}
|
|
110
|
+
</Text>
|
|
111
|
+
</View>
|
|
112
|
+
|
|
113
|
+
<View style={styles.modernInputContainer}>
|
|
114
|
+
<TextField
|
|
115
|
+
ref={inputRef}
|
|
116
|
+
label="Password"
|
|
117
|
+
leading={<Ionicons name="lock-closed-outline" size={24} color={colors.secondaryText} />}
|
|
118
|
+
value={password}
|
|
119
|
+
onChangeText={handlePasswordChange}
|
|
120
|
+
secureTextEntry={!showPassword}
|
|
121
|
+
autoCapitalize="none"
|
|
122
|
+
autoCorrect={false}
|
|
123
|
+
testID="password-input"
|
|
124
|
+
variant="filled"
|
|
125
|
+
error={errorMessage || undefined}
|
|
126
|
+
onSubmitEditing={handleSignInSubmit}
|
|
127
|
+
autoFocus
|
|
128
|
+
/>
|
|
129
|
+
|
|
130
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 16 }}>
|
|
131
|
+
<Text style={[styles.footerText, { color: colors.text }]}>Forgot your password? </Text>
|
|
132
|
+
<TouchableOpacity onPress={() => navigate('RecoverAccount', {
|
|
133
|
+
returnTo: 'SignIn',
|
|
134
|
+
returnStep: 1,
|
|
135
|
+
returnData: { username, userProfile }
|
|
136
|
+
})}>
|
|
137
|
+
<Text style={[styles.modernLinkText, { color: colors.primary }]}>Recover your account</Text>
|
|
138
|
+
</TouchableOpacity>
|
|
139
|
+
</View>
|
|
140
|
+
</View>
|
|
141
|
+
|
|
142
|
+
<GroupedPillButtons
|
|
143
|
+
buttons={[
|
|
144
|
+
{
|
|
145
|
+
text: 'Back',
|
|
146
|
+
onPress: prevStep,
|
|
147
|
+
icon: 'arrow-back',
|
|
148
|
+
variant: 'transparent',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
text: 'Sign In',
|
|
152
|
+
onPress: handleSignInSubmit,
|
|
153
|
+
icon: 'log-in',
|
|
154
|
+
variant: 'primary',
|
|
155
|
+
loading: isLoading,
|
|
156
|
+
testID: 'login-button',
|
|
157
|
+
},
|
|
158
|
+
]}
|
|
159
|
+
colors={colors}
|
|
160
|
+
/>
|
|
161
|
+
|
|
162
|
+
<View style={styles.securityNotice}>
|
|
163
|
+
<Ionicons name="shield-checkmark" size={14} color={colors.secondaryText} />
|
|
164
|
+
<Text style={[styles.securityText, { color: colors.secondaryText }]}>
|
|
165
|
+
Your data is encrypted and secure
|
|
166
|
+
</Text>
|
|
167
|
+
</View>
|
|
168
|
+
</>
|
|
169
|
+
);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export default SignInPasswordStep;
|