@onairos/react-native 3.0.65 → 3.0.67
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/components/DataRequestScreen.js +329 -0
- package/lib/commonjs/components/DataRequestScreen.js.map +1 -0
- package/lib/commonjs/components/EmailVerificationModal.js +7 -6
- package/lib/commonjs/components/EmailVerificationModal.js.map +1 -1
- package/lib/commonjs/components/TrainingModal.js +17 -9
- package/lib/commonjs/components/TrainingModal.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +23 -36
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/services/platformAuthService.js +80 -40
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- package/lib/module/components/DataRequestScreen.js +321 -0
- package/lib/module/components/DataRequestScreen.js.map +1 -0
- package/lib/module/components/EmailVerificationModal.js +7 -6
- package/lib/module/components/EmailVerificationModal.js.map +1 -1
- package/lib/module/components/TrainingModal.js +17 -9
- package/lib/module/components/TrainingModal.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +23 -36
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/services/platformAuthService.js +80 -40
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/typescript/components/DataRequestScreen.d.ts +11 -0
- package/lib/typescript/components/DataRequestScreen.d.ts.map +1 -0
- package/lib/typescript/components/EmailVerificationModal.d.ts +1 -0
- package/lib/typescript/components/EmailVerificationModal.d.ts.map +1 -1
- package/lib/typescript/components/TrainingModal.d.ts.map +1 -1
- package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/services/platformAuthService.d.ts +4 -3
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/DataRequestScreen.tsx +356 -0
- package/src/components/EmailVerificationModal.tsx +10 -6
- package/src/components/TrainingModal.tsx +77 -67
- package/src/components/UniversalOnboarding.tsx +40 -53
- package/src/index.ts +1 -0
- package/src/services/platformAuthService.ts +86 -38
|
@@ -31,6 +31,7 @@ export { PlatformList } from './components/PlatformList';
|
|
|
31
31
|
export { PinInput } from './components/PinInput';
|
|
32
32
|
export { TrainingModal } from './components/TrainingModal';
|
|
33
33
|
export { EmailVerificationModal } from './components/EmailVerificationModal';
|
|
34
|
+
export { DataRequestScreen } from './components/DataRequestScreen';
|
|
34
35
|
export { Overlay } from './components/Overlay';
|
|
35
36
|
export { UniversalOnboarding } from './components/UniversalOnboarding';
|
|
36
37
|
export { OnairosButton } from './components/OnairosButton';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -74,17 +74,18 @@ export declare const updateGoogleClientIds: (config: {
|
|
|
74
74
|
* 📧 EMAIL VERIFICATION FUNCTIONS
|
|
75
75
|
* Using the correct Onairos email verification endpoints
|
|
76
76
|
*/
|
|
77
|
-
export declare const requestEmailVerification: (email: string) => Promise<{
|
|
77
|
+
export declare const requestEmailVerification: (email: string, testMode?: boolean) => Promise<{
|
|
78
78
|
success: boolean;
|
|
79
79
|
message?: string;
|
|
80
80
|
error?: string;
|
|
81
81
|
}>;
|
|
82
|
-
export declare const verifyEmailCode: (email: string, code: string) => Promise<{
|
|
82
|
+
export declare const verifyEmailCode: (email: string, code: string, testMode?: boolean) => Promise<{
|
|
83
83
|
success: boolean;
|
|
84
84
|
message?: string;
|
|
85
85
|
error?: string;
|
|
86
|
+
existingUser?: boolean;
|
|
86
87
|
}>;
|
|
87
|
-
export declare const checkEmailVerificationStatus: (email: string) => Promise<{
|
|
88
|
+
export declare const checkEmailVerificationStatus: (email: string, testMode?: boolean) => Promise<{
|
|
88
89
|
success: boolean;
|
|
89
90
|
isPending?: boolean;
|
|
90
91
|
message?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platformAuthService.d.ts","sourceRoot":"","sources":["../../../src/services/platformAuthService.ts"],"names":[],"mappings":"AAiDA;;GAEG;AACH,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,OAG/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,aAAc,MAAM,KAAG,MAGlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MAGnD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAAoB,MAAM,YAAY,MAAM,YAAY,MAAM,KAAG,QAAQ,MAAM,GAAG,IAAI,CAwH/G,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,aAAa,MAAM,KAAG,QAAQ,OAAO,CA4N7F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,KAAG,MAAM,GAAG,IAW1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,OAG7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBxF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuCpG,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAa,QAAQ,OAAO,CA2D5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAgCxG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,WAAY;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,SAYA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,UAAiB,MAAM,
|
|
1
|
+
{"version":3,"file":"platformAuthService.d.ts","sourceRoot":"","sources":["../../../src/services/platformAuthService.ts"],"names":[],"mappings":"AAiDA;;GAEG;AACH,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,OAG/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,aAAc,MAAM,KAAG,MAGlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAAc,MAAM,KAAG,MAGnD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAAoB,MAAM,YAAY,MAAM,YAAY,MAAM,KAAG,QAAQ,MAAM,GAAG,IAAI,CAwH/G,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,aAAa,MAAM,KAAG,QAAQ,OAAO,CA4N7F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,KAAG,MAAM,GAAG,IAW1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,OAG7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBxF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAa,QAAQ;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuCpG,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAa,QAAQ,OAAO,CA2D5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAgCxG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,WAAY;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,SAYA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,UAAiB,MAAM,yBAAqB,QAAQ;IACvF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAyCA,CAAC;AAEF,eAAO,MAAM,eAAe,UAAiB,MAAM,QAAQ,MAAM,yBAAqB,QAAQ;IAC5F,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CA0DA,CAAC;AAEF,eAAO,MAAM,4BAA4B,UAAiB,MAAM,yBAAqB,QAAQ;IAC3F,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAuDA,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,YAAY,MAAM,KAAG,QAAQ;IACpF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAuCA,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
ScrollView,
|
|
8
|
+
Image,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
11
|
+
import { COLORS } from '../constants';
|
|
12
|
+
|
|
13
|
+
interface DataRequestScreenProps {
|
|
14
|
+
onAccept: () => void;
|
|
15
|
+
onDecline: () => void;
|
|
16
|
+
requestData: Record<string, any>;
|
|
17
|
+
AppName: string;
|
|
18
|
+
appIcon?: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const DataRequestScreen: React.FC<DataRequestScreenProps> = ({
|
|
22
|
+
onAccept,
|
|
23
|
+
onDecline,
|
|
24
|
+
requestData,
|
|
25
|
+
AppName,
|
|
26
|
+
appIcon,
|
|
27
|
+
}) => {
|
|
28
|
+
|
|
29
|
+
// Basic data requests that are always shown
|
|
30
|
+
const basicRequests = [
|
|
31
|
+
{
|
|
32
|
+
key: 'basic_profile',
|
|
33
|
+
name: 'Basic Profile',
|
|
34
|
+
description: 'Your basic social media profile information',
|
|
35
|
+
reward: 'Personalized experience',
|
|
36
|
+
icon: 'person'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: 'content_analysis',
|
|
40
|
+
name: 'Content Analysis',
|
|
41
|
+
description: 'Analysis of your posts and interactions',
|
|
42
|
+
reward: 'Better recommendations',
|
|
43
|
+
icon: 'analytics'
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const renderDataRequest = (data: any, key: string, isBasic = false) => {
|
|
48
|
+
let name, description, reward, icon;
|
|
49
|
+
|
|
50
|
+
if (isBasic) {
|
|
51
|
+
({ name, description, reward, icon } = data);
|
|
52
|
+
} else {
|
|
53
|
+
// Handle new format (personality_traits, sentiment_analysis)
|
|
54
|
+
if ('name' in data && 'description' in data && 'reward' in data) {
|
|
55
|
+
name = data.name;
|
|
56
|
+
description = data.description;
|
|
57
|
+
reward = data.reward;
|
|
58
|
+
icon = key === 'personality_traits' ? 'psychology' : 'analytics';
|
|
59
|
+
} else if ('type' in data && 'descriptions' in data && 'reward' in data) {
|
|
60
|
+
// Handle old format (Small, Medium, Large)
|
|
61
|
+
name = `${key} - ${data.type}`;
|
|
62
|
+
description = data.descriptions;
|
|
63
|
+
reward = data.reward;
|
|
64
|
+
icon = 'data_usage';
|
|
65
|
+
} else {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<View key={key} style={styles.dataRequestContainer}>
|
|
72
|
+
<View style={styles.dataRequestHeader}>
|
|
73
|
+
<View style={styles.iconContainer}>
|
|
74
|
+
<Icon
|
|
75
|
+
name={icon}
|
|
76
|
+
size={24}
|
|
77
|
+
color={COLORS.primary}
|
|
78
|
+
/>
|
|
79
|
+
</View>
|
|
80
|
+
<View style={styles.requestContent}>
|
|
81
|
+
<Text style={styles.dataRequestName}>{name}</Text>
|
|
82
|
+
<Text style={styles.dataRequestDescription}>{description}</Text>
|
|
83
|
+
<View style={styles.rewardContainer}>
|
|
84
|
+
<Icon name="star" size={16} color="#FFD700" />
|
|
85
|
+
<Text style={styles.rewardText}>{reward}</Text>
|
|
86
|
+
</View>
|
|
87
|
+
</View>
|
|
88
|
+
</View>
|
|
89
|
+
</View>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const renderCustomRequests = () => {
|
|
94
|
+
return Object.entries(requestData).map(([key, data]) => {
|
|
95
|
+
// Skip if data is undefined or doesn't have the expected structure
|
|
96
|
+
if (!data || typeof data !== 'object') return null;
|
|
97
|
+
return renderDataRequest(data, key, false);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<View style={styles.container}>
|
|
103
|
+
{/* Header */}
|
|
104
|
+
<View style={styles.header}>
|
|
105
|
+
<View style={styles.titleContainer}>
|
|
106
|
+
<Text style={styles.title}>Data Sharing Request</Text>
|
|
107
|
+
<Text style={styles.subtitle}>
|
|
108
|
+
{AppName} would like access to the following data
|
|
109
|
+
</Text>
|
|
110
|
+
</View>
|
|
111
|
+
|
|
112
|
+
{/* App Icon Flow: Onairos → Your App */}
|
|
113
|
+
<View style={styles.iconFlow}>
|
|
114
|
+
<Image
|
|
115
|
+
source={require('../assets/images/onairos_logo.png')}
|
|
116
|
+
style={styles.onairosIcon}
|
|
117
|
+
resizeMode="contain"
|
|
118
|
+
/>
|
|
119
|
+
<Icon name="arrow-forward" size={24} color="#666" style={styles.arrowIcon} />
|
|
120
|
+
{appIcon ? (
|
|
121
|
+
<Image
|
|
122
|
+
source={appIcon}
|
|
123
|
+
style={styles.appIcon}
|
|
124
|
+
resizeMode="contain"
|
|
125
|
+
/>
|
|
126
|
+
) : (
|
|
127
|
+
<View style={styles.appIconPlaceholder}>
|
|
128
|
+
<Text style={styles.appIconText}>
|
|
129
|
+
{AppName.charAt(0).toUpperCase()}
|
|
130
|
+
</Text>
|
|
131
|
+
</View>
|
|
132
|
+
)}
|
|
133
|
+
</View>
|
|
134
|
+
</View>
|
|
135
|
+
|
|
136
|
+
{/* Data Requests */}
|
|
137
|
+
<ScrollView
|
|
138
|
+
style={styles.content}
|
|
139
|
+
contentContainerStyle={styles.scrollContent}
|
|
140
|
+
showsVerticalScrollIndicator={false}
|
|
141
|
+
>
|
|
142
|
+
{/* Basic Requests (always shown) */}
|
|
143
|
+
<View style={styles.section}>
|
|
144
|
+
<Text style={styles.sectionTitle}>Basic Data</Text>
|
|
145
|
+
{basicRequests.map((request) => renderDataRequest(request, request.key, true))}
|
|
146
|
+
</View>
|
|
147
|
+
|
|
148
|
+
{/* Custom Requests (from developer) */}
|
|
149
|
+
{Object.keys(requestData).length > 0 && (
|
|
150
|
+
<View style={styles.section}>
|
|
151
|
+
<Text style={styles.sectionTitle}>Additional Insights</Text>
|
|
152
|
+
{renderCustomRequests()}
|
|
153
|
+
</View>
|
|
154
|
+
)}
|
|
155
|
+
|
|
156
|
+
{/* Privacy Note */}
|
|
157
|
+
<View style={styles.privacyNote}>
|
|
158
|
+
<Icon name="security" size={20} color="#28a745" />
|
|
159
|
+
<Text style={styles.privacyText}>
|
|
160
|
+
Your data is encrypted and never shared with third parties
|
|
161
|
+
</Text>
|
|
162
|
+
</View>
|
|
163
|
+
</ScrollView>
|
|
164
|
+
|
|
165
|
+
{/* Footer Buttons */}
|
|
166
|
+
<View style={styles.footer}>
|
|
167
|
+
<TouchableOpacity
|
|
168
|
+
style={styles.declineButton}
|
|
169
|
+
onPress={onDecline}
|
|
170
|
+
>
|
|
171
|
+
<Text style={styles.declineButtonText}>Decline</Text>
|
|
172
|
+
</TouchableOpacity>
|
|
173
|
+
|
|
174
|
+
<TouchableOpacity
|
|
175
|
+
style={styles.acceptButton}
|
|
176
|
+
onPress={onAccept}
|
|
177
|
+
>
|
|
178
|
+
<Text style={styles.acceptButtonText}>Accept & Continue</Text>
|
|
179
|
+
</TouchableOpacity>
|
|
180
|
+
</View>
|
|
181
|
+
</View>
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const styles = StyleSheet.create({
|
|
186
|
+
container: {
|
|
187
|
+
flex: 1,
|
|
188
|
+
backgroundColor: '#fff',
|
|
189
|
+
},
|
|
190
|
+
header: {
|
|
191
|
+
padding: 24,
|
|
192
|
+
paddingTop: 40,
|
|
193
|
+
backgroundColor: '#f8f9fa',
|
|
194
|
+
borderBottomWidth: 1,
|
|
195
|
+
borderBottomColor: '#e9ecef',
|
|
196
|
+
},
|
|
197
|
+
titleContainer: {
|
|
198
|
+
marginBottom: 20,
|
|
199
|
+
},
|
|
200
|
+
title: {
|
|
201
|
+
fontSize: 24,
|
|
202
|
+
fontWeight: '600',
|
|
203
|
+
color: '#000',
|
|
204
|
+
textAlign: 'center',
|
|
205
|
+
marginBottom: 8,
|
|
206
|
+
},
|
|
207
|
+
subtitle: {
|
|
208
|
+
fontSize: 16,
|
|
209
|
+
color: '#666',
|
|
210
|
+
textAlign: 'center',
|
|
211
|
+
},
|
|
212
|
+
iconFlow: {
|
|
213
|
+
flexDirection: 'row',
|
|
214
|
+
alignItems: 'center',
|
|
215
|
+
justifyContent: 'center',
|
|
216
|
+
},
|
|
217
|
+
onairosIcon: {
|
|
218
|
+
width: 32,
|
|
219
|
+
height: 32,
|
|
220
|
+
},
|
|
221
|
+
arrowIcon: {
|
|
222
|
+
marginHorizontal: 12,
|
|
223
|
+
},
|
|
224
|
+
appIcon: {
|
|
225
|
+
width: 32,
|
|
226
|
+
height: 32,
|
|
227
|
+
borderRadius: 8,
|
|
228
|
+
},
|
|
229
|
+
appIconPlaceholder: {
|
|
230
|
+
width: 32,
|
|
231
|
+
height: 32,
|
|
232
|
+
borderRadius: 8,
|
|
233
|
+
backgroundColor: COLORS.primary,
|
|
234
|
+
alignItems: 'center',
|
|
235
|
+
justifyContent: 'center',
|
|
236
|
+
},
|
|
237
|
+
appIconText: {
|
|
238
|
+
color: '#fff',
|
|
239
|
+
fontSize: 16,
|
|
240
|
+
fontWeight: '600',
|
|
241
|
+
},
|
|
242
|
+
content: {
|
|
243
|
+
flex: 1,
|
|
244
|
+
},
|
|
245
|
+
scrollContent: {
|
|
246
|
+
padding: 20,
|
|
247
|
+
},
|
|
248
|
+
section: {
|
|
249
|
+
marginBottom: 24,
|
|
250
|
+
},
|
|
251
|
+
sectionTitle: {
|
|
252
|
+
fontSize: 18,
|
|
253
|
+
fontWeight: '600',
|
|
254
|
+
color: '#000',
|
|
255
|
+
marginBottom: 16,
|
|
256
|
+
},
|
|
257
|
+
dataRequestContainer: {
|
|
258
|
+
marginBottom: 16,
|
|
259
|
+
borderWidth: 1,
|
|
260
|
+
borderColor: '#e9ecef',
|
|
261
|
+
borderRadius: 12,
|
|
262
|
+
padding: 16,
|
|
263
|
+
backgroundColor: '#fff',
|
|
264
|
+
},
|
|
265
|
+
dataRequestHeader: {
|
|
266
|
+
flexDirection: 'row',
|
|
267
|
+
alignItems: 'flex-start',
|
|
268
|
+
},
|
|
269
|
+
iconContainer: {
|
|
270
|
+
width: 40,
|
|
271
|
+
height: 40,
|
|
272
|
+
borderRadius: 20,
|
|
273
|
+
backgroundColor: '#f0f8ff',
|
|
274
|
+
alignItems: 'center',
|
|
275
|
+
justifyContent: 'center',
|
|
276
|
+
marginRight: 12,
|
|
277
|
+
},
|
|
278
|
+
requestContent: {
|
|
279
|
+
flex: 1,
|
|
280
|
+
},
|
|
281
|
+
dataRequestName: {
|
|
282
|
+
fontSize: 16,
|
|
283
|
+
fontWeight: '600',
|
|
284
|
+
color: '#000',
|
|
285
|
+
marginBottom: 4,
|
|
286
|
+
},
|
|
287
|
+
dataRequestDescription: {
|
|
288
|
+
fontSize: 14,
|
|
289
|
+
color: '#666',
|
|
290
|
+
lineHeight: 20,
|
|
291
|
+
marginBottom: 8,
|
|
292
|
+
},
|
|
293
|
+
rewardContainer: {
|
|
294
|
+
flexDirection: 'row',
|
|
295
|
+
alignItems: 'center',
|
|
296
|
+
backgroundColor: '#fff3cd',
|
|
297
|
+
padding: 6,
|
|
298
|
+
borderRadius: 6,
|
|
299
|
+
alignSelf: 'flex-start',
|
|
300
|
+
},
|
|
301
|
+
rewardText: {
|
|
302
|
+
fontSize: 12,
|
|
303
|
+
fontWeight: '500',
|
|
304
|
+
marginLeft: 4,
|
|
305
|
+
color: '#856404',
|
|
306
|
+
},
|
|
307
|
+
privacyNote: {
|
|
308
|
+
flexDirection: 'row',
|
|
309
|
+
alignItems: 'center',
|
|
310
|
+
backgroundColor: '#d4edda',
|
|
311
|
+
padding: 12,
|
|
312
|
+
borderRadius: 8,
|
|
313
|
+
marginTop: 8,
|
|
314
|
+
},
|
|
315
|
+
privacyText: {
|
|
316
|
+
fontSize: 14,
|
|
317
|
+
color: '#155724',
|
|
318
|
+
marginLeft: 8,
|
|
319
|
+
flex: 1,
|
|
320
|
+
},
|
|
321
|
+
footer: {
|
|
322
|
+
flexDirection: 'row',
|
|
323
|
+
padding: 20,
|
|
324
|
+
borderTopWidth: 1,
|
|
325
|
+
borderTopColor: '#e9ecef',
|
|
326
|
+
backgroundColor: '#fff',
|
|
327
|
+
},
|
|
328
|
+
declineButton: {
|
|
329
|
+
flex: 1,
|
|
330
|
+
paddingVertical: 16,
|
|
331
|
+
paddingHorizontal: 24,
|
|
332
|
+
borderRadius: 12,
|
|
333
|
+
borderWidth: 1,
|
|
334
|
+
borderColor: '#dc3545',
|
|
335
|
+
marginRight: 12,
|
|
336
|
+
alignItems: 'center',
|
|
337
|
+
},
|
|
338
|
+
declineButtonText: {
|
|
339
|
+
fontSize: 16,
|
|
340
|
+
fontWeight: '600',
|
|
341
|
+
color: '#dc3545',
|
|
342
|
+
},
|
|
343
|
+
acceptButton: {
|
|
344
|
+
flex: 2,
|
|
345
|
+
paddingVertical: 16,
|
|
346
|
+
paddingHorizontal: 24,
|
|
347
|
+
borderRadius: 12,
|
|
348
|
+
backgroundColor: '#28a745',
|
|
349
|
+
alignItems: 'center',
|
|
350
|
+
},
|
|
351
|
+
acceptButtonText: {
|
|
352
|
+
fontSize: 16,
|
|
353
|
+
fontWeight: '600',
|
|
354
|
+
color: '#fff',
|
|
355
|
+
},
|
|
356
|
+
});
|
|
@@ -20,6 +20,7 @@ export interface EmailVerificationModalProps {
|
|
|
20
20
|
onClose: () => void;
|
|
21
21
|
onVerificationComplete: (email: string, isExistingUser: boolean) => void;
|
|
22
22
|
onVerificationFailed: (error: string) => void;
|
|
23
|
+
testMode?: boolean;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
@@ -28,6 +29,7 @@ export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
|
28
29
|
onClose,
|
|
29
30
|
onVerificationComplete,
|
|
30
31
|
onVerificationFailed,
|
|
32
|
+
testMode = false,
|
|
31
33
|
}) => {
|
|
32
34
|
const [step, setStep] = useState<'request' | 'verify'>('request');
|
|
33
35
|
const [verificationCode, setVerificationCode] = useState<string>('');
|
|
@@ -45,7 +47,7 @@ export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
|
45
47
|
console.log('📧 Requesting email verification for:', email);
|
|
46
48
|
|
|
47
49
|
// First check if there's already a pending verification
|
|
48
|
-
const statusCheck = await checkEmailVerificationStatus(email);
|
|
50
|
+
const statusCheck = await checkEmailVerificationStatus(email, testMode);
|
|
49
51
|
if (statusCheck.success && statusCheck.isPending) {
|
|
50
52
|
console.log('✅ Email verification already pending');
|
|
51
53
|
setCodeSent(true);
|
|
@@ -55,7 +57,7 @@ export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// Request new verification code
|
|
58
|
-
const result = await requestEmailVerification(email);
|
|
60
|
+
const result = await requestEmailVerification(email, testMode);
|
|
59
61
|
|
|
60
62
|
if (result.success) {
|
|
61
63
|
console.log('✅ Email verification code requested successfully');
|
|
@@ -91,7 +93,7 @@ export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
|
91
93
|
try {
|
|
92
94
|
console.log('🔍 Verifying email code for:', email);
|
|
93
95
|
|
|
94
|
-
const result = await verifyEmailCode(email, verificationCode.trim());
|
|
96
|
+
const result = await verifyEmailCode(email, verificationCode.trim(), testMode);
|
|
95
97
|
|
|
96
98
|
if (result.success) {
|
|
97
99
|
console.log('✅ Email verification successful');
|
|
@@ -190,9 +192,11 @@ export const EmailVerificationModal: React.FC<EmailVerificationModalProps> = ({
|
|
|
190
192
|
We've sent a 6-digit code to {email}
|
|
191
193
|
</Text>
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
{testMode && (
|
|
196
|
+
<Text style={styles.testingNote}>
|
|
197
|
+
🔍 Test Mode: Any 6-digit code will work for verification
|
|
198
|
+
</Text>
|
|
199
|
+
)}
|
|
196
200
|
|
|
197
201
|
<TextInput
|
|
198
202
|
style={styles.codeInput}
|
|
@@ -63,6 +63,7 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
console.log('🚀 Starting Enoch training with socketId:', socketId);
|
|
66
|
+
console.log('🔍 Production mode: Using live training API');
|
|
66
67
|
|
|
67
68
|
// Prepare user data for training
|
|
68
69
|
const trainingData = {
|
|
@@ -95,16 +96,18 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
95
96
|
console.error('Training start failed:', result.error);
|
|
96
97
|
setTrainingStatus(`Error: ${result.error}`);
|
|
97
98
|
setHasError(true);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
setInternalProgress(20);
|
|
99
|
+
|
|
100
|
+
// In production mode, don't fallback to simulation on API failure
|
|
101
|
+
console.error('🚨 Production mode: Training failed, not falling back to simulation');
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
} catch (error) {
|
|
105
105
|
console.error('Training start error:', error);
|
|
106
106
|
setTrainingStatus(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
107
107
|
setHasError(true);
|
|
108
|
+
|
|
109
|
+
// In production mode, show the actual error
|
|
110
|
+
console.error('🚨 Production mode: Training failed with error:', error);
|
|
108
111
|
}
|
|
109
112
|
};
|
|
110
113
|
|
|
@@ -170,72 +173,79 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
170
173
|
|
|
171
174
|
// Initialize real socket connection - backend confirmed this is working
|
|
172
175
|
try {
|
|
173
|
-
|
|
174
|
-
socketRef.current = io('https://api2.onairos.uk', {
|
|
175
|
-
transports: ['websocket'],
|
|
176
|
-
autoConnect: false
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// Socket event listeners
|
|
180
|
-
socketRef.current.on('connect', () => {
|
|
181
|
-
console.log('✅ Socket connected for training');
|
|
182
|
-
setSocketConnected(true);
|
|
183
|
-
const socketId = socketRef.current?.id;
|
|
184
|
-
if (socketId) {
|
|
185
|
-
startEnochTraining(socketId);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
socketRef.current.on('disconnect', () => {
|
|
190
|
-
console.log('❌ Socket disconnected');
|
|
191
|
-
setSocketConnected(false);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
socketRef.current.on('trainingCompleted', (data) => {
|
|
195
|
-
console.log('✅ Training Complete:', data);
|
|
196
|
-
setTrainingStatus('Running test inference...');
|
|
197
|
-
setInternalProgress(60);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
socketRef.current.on('inferenceCompleted', (data) => {
|
|
201
|
-
console.log('🧠 Inference Complete:', data);
|
|
202
|
-
setTrainingStatus('Uploading to S3...');
|
|
203
|
-
setInternalProgress(80);
|
|
204
|
-
setUserTraits(data.traits);
|
|
205
|
-
setInferenceResults(data.inferenceResults);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
socketRef.current.on('modelStandby', (data) => {
|
|
209
|
-
console.log('🎉 All Complete:', data);
|
|
210
|
-
setIsTrainingComplete(true);
|
|
211
|
-
setTrainingStatus('Complete!');
|
|
212
|
-
setInternalProgress(100);
|
|
176
|
+
console.log('🔌 Production mode: Initializing real socket connection');
|
|
213
177
|
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
console.
|
|
223
|
-
|
|
178
|
+
// Initialize socket connection
|
|
179
|
+
socketRef.current = io('https://api2.onairos.uk', {
|
|
180
|
+
transports: ['websocket'],
|
|
181
|
+
autoConnect: false
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Socket event listeners
|
|
185
|
+
socketRef.current.on('connect', () => {
|
|
186
|
+
console.log('✅ Socket connected for training');
|
|
187
|
+
setSocketConnected(true);
|
|
188
|
+
const socketId = socketRef.current?.id;
|
|
189
|
+
if (socketId) {
|
|
190
|
+
startEnochTraining(socketId);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
socketRef.current.on('disconnect', () => {
|
|
195
|
+
console.log('❌ Socket disconnected');
|
|
196
|
+
setSocketConnected(false);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
socketRef.current.on('connect_error', (error) => {
|
|
200
|
+
console.error('❌ Socket connection error:', error);
|
|
201
|
+
setTrainingStatus('Connection failed');
|
|
224
202
|
setHasError(true);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
socketRef.current.on('trainingCompleted', (data) => {
|
|
206
|
+
console.log('✅ Training Complete:', data);
|
|
207
|
+
setTrainingStatus('Running test inference...');
|
|
208
|
+
setInternalProgress(60);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
socketRef.current.on('inferenceCompleted', (data) => {
|
|
212
|
+
console.log('🧠 Inference Complete:', data);
|
|
213
|
+
setTrainingStatus('Uploading to S3...');
|
|
214
|
+
setInternalProgress(80);
|
|
215
|
+
setUserTraits(data.traits);
|
|
216
|
+
setInferenceResults(data.inferenceResults);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
socketRef.current.on('modelStandby', (data) => {
|
|
220
|
+
console.log('🎉 All Complete:', data);
|
|
221
|
+
setIsTrainingComplete(true);
|
|
222
|
+
setTrainingStatus('Complete!');
|
|
223
|
+
setInternalProgress(100);
|
|
224
|
+
|
|
225
|
+
// Auto-complete after a short delay
|
|
226
|
+
setTimeout(() => {
|
|
227
|
+
onComplete && onComplete();
|
|
228
|
+
}, 1500);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
socketRef.current.on('trainingUpdate', (data) => {
|
|
232
|
+
if (data.error) {
|
|
233
|
+
console.error('Training update error:', data.error);
|
|
234
|
+
setTrainingStatus(`Error: ${data.error}`);
|
|
235
|
+
setHasError(true);
|
|
236
|
+
} else if (data.progress) {
|
|
237
|
+
setInternalProgress(data.progress);
|
|
238
|
+
setTrainingStatus(data.status || 'Training in progress...');
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Connect to socket
|
|
243
|
+
socketRef.current.connect();
|
|
244
|
+
|
|
233
245
|
} catch (socketError) {
|
|
234
|
-
console.error('Socket connection failed
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
setSocketConnected(true);
|
|
238
|
-
simulateTraining();
|
|
246
|
+
console.error('🚨 Production mode: Socket connection failed:', socketError);
|
|
247
|
+
setTrainingStatus('Failed to connect to training service');
|
|
248
|
+
setHasError(true);
|
|
239
249
|
}
|
|
240
250
|
|
|
241
251
|
// Cleanup function
|