@onairos/react-native 3.0.22 → 3.0.25
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/OnairosButton.js +2 -3
- package/lib/commonjs/components/OnairosButton.js.map +1 -1
- package/lib/commonjs/components/TrainingModal.js +120 -16
- package/lib/commonjs/components/TrainingModal.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +242 -39
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/components/onboarding/OAuthWebView.js +138 -27
- package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/commonjs/constants/index.js +3 -2
- package/lib/commonjs/constants/index.js.map +1 -1
- package/lib/commonjs/services/platformAuthService.js +227 -0
- package/lib/commonjs/services/platformAuthService.js.map +1 -0
- package/lib/module/components/OnairosButton.js +2 -3
- package/lib/module/components/OnairosButton.js.map +1 -1
- package/lib/module/components/TrainingModal.js +120 -17
- package/lib/module/components/TrainingModal.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +243 -40
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/components/onboarding/OAuthWebView.js +139 -28
- package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/module/constants/index.js +3 -2
- package/lib/module/constants/index.js.map +1 -1
- package/lib/module/services/platformAuthService.js +213 -0
- package/lib/module/services/platformAuthService.js.map +1 -0
- package/lib/typescript/components/OnairosButton.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/components/onboarding/OAuthWebView.d.ts.map +1 -1
- package/lib/typescript/constants/index.d.ts +1 -0
- package/lib/typescript/constants/index.d.ts.map +1 -1
- package/lib/typescript/services/platformAuthService.d.ts +45 -0
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -0
- package/package.json +2 -1
- package/src/components/OnairosButton.tsx +1 -4
- package/src/components/TrainingModal.tsx +202 -61
- package/src/components/UniversalOnboarding.tsx +232 -35
- package/src/components/onboarding/OAuthWebView.tsx +135 -25
- package/src/constants/index.ts +3 -2
- package/src/services/platformAuthService.ts +241 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;CAkBlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAyBpD,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;CAczB,CAAC;AAEF,eAAO,MAAM,YAAY;;;CAGxB,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;CAM5B,CAAC;AAEF,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;CAkBlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAyBpD,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;CAczB,CAAC;AAEF,eAAO,MAAM,YAAY;;;CAGxB,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;CAM5B,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;CAI5B,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a native SDK is available for the given platform
|
|
3
|
+
*/
|
|
4
|
+
export declare const hasNativeSDK: (platform: string) => boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Gets the auth endpoint URL for a platform
|
|
7
|
+
*/
|
|
8
|
+
export declare const getAuthEndpoint: (platform: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Gets the color associated with a platform
|
|
11
|
+
*/
|
|
12
|
+
export declare const getPlatformColor: (platform: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Initiates the OAuth flow for a platform using Onairos proxy
|
|
15
|
+
* @param platform The platform to authenticate with
|
|
16
|
+
* @param userEmail The authenticated user's email (not random username)
|
|
17
|
+
* @returns A Promise that resolves to the OAuth URL to open in a WebView
|
|
18
|
+
*/
|
|
19
|
+
export declare const initiateOAuth: (platform: string, userEmail: string) => Promise<string | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Initiates the native SDK authentication flow for a platform
|
|
22
|
+
* @param platform The platform to authenticate with
|
|
23
|
+
* @returns A Promise that resolves to the authentication result
|
|
24
|
+
*/
|
|
25
|
+
export declare const initiateNativeAuth: (platform: string) => Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Handles the OAuth callback
|
|
28
|
+
* @param url The callback URL
|
|
29
|
+
* @returns The authorization code extracted from the URL
|
|
30
|
+
*/
|
|
31
|
+
export declare const handleOAuthCallback: (url: string) => string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if a URL is an OAuth callback
|
|
34
|
+
* @param url The URL to check
|
|
35
|
+
* @returns True if the URL is an OAuth callback
|
|
36
|
+
*/
|
|
37
|
+
export declare const isOAuthCallback: (url: string) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Detects if OAuth flow has completed successfully based on URL patterns
|
|
40
|
+
* @param url The current URL in the WebView
|
|
41
|
+
* @param platform The platform being authenticated
|
|
42
|
+
* @returns True if the OAuth flow has completed successfully
|
|
43
|
+
*/
|
|
44
|
+
export declare const isOAuthSuccess: (url: string, platform: string) => boolean;
|
|
45
|
+
//# sourceMappingURL=platformAuthService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platformAuthService.d.ts","sourceRoot":"","sources":["../../../src/services/platformAuthService.ts"],"names":[],"mappings":"AAwCA;;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;;;;;GAKG;AACH,eAAO,MAAM,aAAa,aAAoB,MAAM,aAAa,MAAM,KAAG,QAAQ,MAAM,GAAG,IAAI,CAmE9F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAoB,MAAM,KAAG,QAAQ,OAAO,CAS1E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,KAAG,MAAM,GAAG,IAgB1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,OAS7C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAS,MAAM,YAAY,MAAM,KAAG,OAwC9D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onairos/react-native",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.25",
|
|
4
4
|
"description": "Onairos React Native SDK for social media authentication and AI model training",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@react-native-community/netinfo": "^9.0.0",
|
|
67
|
+
"@react-native-google-signin/google-signin": "^14.0.1",
|
|
67
68
|
"axios": "^1.6.2",
|
|
68
69
|
"react-native-crypto-js": "^1.0.0",
|
|
69
70
|
"react-native-device-info": "^10.8.0",
|
|
@@ -15,7 +15,6 @@ import { COLORS } from '../constants';
|
|
|
15
15
|
import type { OnairosButtonProps } from '../types';
|
|
16
16
|
import { hasCredentials, getCredentials, deleteCredentials as clearCredentials } from '../utils/secureStorage';
|
|
17
17
|
import { onairosApi } from '../api';
|
|
18
|
-
import { Portal } from '../utils/Portal';
|
|
19
18
|
|
|
20
19
|
export interface OnairosButtonRef {
|
|
21
20
|
trigger: () => Promise<void>;
|
|
@@ -304,9 +303,8 @@ export const OnairosButton = forwardRef<OnairosButtonRef, OnairosButtonProps>(({
|
|
|
304
303
|
/>
|
|
305
304
|
)}
|
|
306
305
|
|
|
307
|
-
{/* Overlay rendered
|
|
306
|
+
{/* Overlay rendered directly without Portal */}
|
|
308
307
|
{showOverlay && storedCredentials && (
|
|
309
|
-
<Portal>
|
|
310
308
|
<Overlay
|
|
311
309
|
data={requestData || {}}
|
|
312
310
|
username={storedCredentials.username}
|
|
@@ -315,7 +313,6 @@ export const OnairosButton = forwardRef<OnairosButtonRef, OnairosButtonProps>(({
|
|
|
315
313
|
appName={AppName}
|
|
316
314
|
darkMode={darkMode}
|
|
317
315
|
/>
|
|
318
|
-
</Portal>
|
|
319
316
|
)}
|
|
320
317
|
</>
|
|
321
318
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
View,
|
|
4
4
|
Text,
|
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
Animated,
|
|
11
11
|
TouchableWithoutFeedback,
|
|
12
12
|
SafeAreaView,
|
|
13
|
+
TextInput,
|
|
14
|
+
KeyboardAvoidingView,
|
|
15
|
+
Platform,
|
|
13
16
|
} from 'react-native';
|
|
14
17
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
15
18
|
import { COLORS } from '../constants';
|
|
@@ -17,6 +20,18 @@ import type { TrainingModalProps } from '../types';
|
|
|
17
20
|
|
|
18
21
|
const { width, height } = Dimensions.get('window');
|
|
19
22
|
|
|
23
|
+
// Dynamic training messages that appear during the process
|
|
24
|
+
const TRAINING_MESSAGES = [
|
|
25
|
+
"Loading your data...",
|
|
26
|
+
"Analyzing your digital footprint...",
|
|
27
|
+
"Your mind is very unique...",
|
|
28
|
+
"Creating your AI persona...",
|
|
29
|
+
"Building neural pathways...",
|
|
30
|
+
"Finalizing your digital twin...",
|
|
31
|
+
"Almost ready...",
|
|
32
|
+
"Training complete!"
|
|
33
|
+
];
|
|
34
|
+
|
|
20
35
|
export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
21
36
|
visible,
|
|
22
37
|
progress,
|
|
@@ -26,8 +41,47 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
26
41
|
modelKey,
|
|
27
42
|
username,
|
|
28
43
|
}) => {
|
|
44
|
+
const [email, setEmail] = useState<string>('');
|
|
45
|
+
const [showEmailInput, setShowEmailInput] = useState<boolean>(false);
|
|
46
|
+
const [currentMessage, setCurrentMessage] = useState<string>(TRAINING_MESSAGES[0]);
|
|
47
|
+
const [messageIndex, setMessageIndex] = useState<number>(0);
|
|
48
|
+
|
|
29
49
|
const progressPercentage = Math.round(progress * 100);
|
|
30
50
|
|
|
51
|
+
// Update training message based on progress
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (progress > 0) {
|
|
54
|
+
const newIndex = Math.min(
|
|
55
|
+
Math.floor(progress * TRAINING_MESSAGES.length),
|
|
56
|
+
TRAINING_MESSAGES.length - 1
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (newIndex !== messageIndex) {
|
|
60
|
+
setMessageIndex(newIndex);
|
|
61
|
+
setCurrentMessage(TRAINING_MESSAGES[newIndex]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, [progress, messageIndex]);
|
|
65
|
+
|
|
66
|
+
// Show email input when training is complete
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (progress >= 1 && !showEmailInput) {
|
|
69
|
+
setShowEmailInput(true);
|
|
70
|
+
}
|
|
71
|
+
}, [progress, showEmailInput]);
|
|
72
|
+
|
|
73
|
+
const handleEmailSubmit = () => {
|
|
74
|
+
if (email.trim() && onComplete) {
|
|
75
|
+
// Pass email data to the completion handler
|
|
76
|
+
onComplete();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const isValidEmail = (email: string): boolean => {
|
|
81
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
82
|
+
return emailRegex.test(email);
|
|
83
|
+
};
|
|
84
|
+
|
|
31
85
|
return (
|
|
32
86
|
<Modal
|
|
33
87
|
visible={visible}
|
|
@@ -36,65 +90,119 @@ export const TrainingModal: React.FC<TrainingModalProps> = ({
|
|
|
36
90
|
statusBarTranslucent
|
|
37
91
|
onRequestClose={onCancel}
|
|
38
92
|
>
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
style={
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
]}
|
|
63
|
-
/>
|
|
64
|
-
</View>
|
|
65
|
-
<Text style={styles.progressText}>{progressPercentage}%</Text>
|
|
66
|
-
</View>
|
|
93
|
+
<KeyboardAvoidingView
|
|
94
|
+
style={styles.modalOverlay}
|
|
95
|
+
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
|
96
|
+
>
|
|
97
|
+
<TouchableWithoutFeedback>
|
|
98
|
+
<View style={styles.modalOverlay}>
|
|
99
|
+
<TouchableWithoutFeedback>
|
|
100
|
+
<View style={styles.bottomSheet}>
|
|
101
|
+
<View style={styles.handleContainer}>
|
|
102
|
+
<View style={styles.handle} />
|
|
103
|
+
</View>
|
|
104
|
+
|
|
105
|
+
<SafeAreaView style={styles.container}>
|
|
106
|
+
<View style={styles.content}>
|
|
107
|
+
{!showEmailInput ? (
|
|
108
|
+
<>
|
|
109
|
+
{/* Training in progress */}
|
|
110
|
+
<Icon name="auto_awesome" size={48} color={COLORS.primary} />
|
|
111
|
+
|
|
112
|
+
<Text style={styles.title}>Training Your AI Model</Text>
|
|
113
|
+
<Text style={styles.subtitle}>
|
|
114
|
+
We're analyzing your social media data to create your personalized AI model
|
|
115
|
+
</Text>
|
|
67
116
|
|
|
68
|
-
|
|
117
|
+
<View style={styles.progressContainer}>
|
|
118
|
+
<View style={styles.progressBar}>
|
|
119
|
+
<Animated.View
|
|
120
|
+
style={[
|
|
121
|
+
styles.progressFill,
|
|
122
|
+
{ width: `${progressPercentage}%` },
|
|
123
|
+
]}
|
|
124
|
+
/>
|
|
125
|
+
</View>
|
|
126
|
+
<Text style={styles.progressText}>{progressPercentage}%</Text>
|
|
127
|
+
</View>
|
|
69
128
|
|
|
70
|
-
|
|
71
|
-
<ActivityIndicator size="small" color={COLORS.primary} />
|
|
72
|
-
<Text style={styles.loadingText}>Processing your data...</Text>
|
|
73
|
-
</View>
|
|
129
|
+
<Text style={styles.etaText}>Estimated time remaining: {eta}</Text>
|
|
74
130
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
131
|
+
<View style={styles.loadingContainer}>
|
|
132
|
+
<ActivityIndicator size="small" color={COLORS.primary} />
|
|
133
|
+
<Text style={styles.loadingText}>{currentMessage}</Text>
|
|
134
|
+
</View>
|
|
135
|
+
|
|
136
|
+
<View style={styles.footer}>
|
|
137
|
+
<TouchableOpacity
|
|
138
|
+
style={styles.cancelButton}
|
|
139
|
+
onPress={onCancel}
|
|
140
|
+
>
|
|
141
|
+
<Text style={styles.cancelButtonText}>Cancel</Text>
|
|
142
|
+
</TouchableOpacity>
|
|
143
|
+
</View>
|
|
144
|
+
</>
|
|
145
|
+
) : (
|
|
146
|
+
<>
|
|
147
|
+
{/* Training complete - Email input */}
|
|
148
|
+
<Icon name="check_circle" size={48} color="#4CAF50" />
|
|
149
|
+
|
|
150
|
+
<Text style={styles.title}>Training Complete!</Text>
|
|
151
|
+
<Text style={styles.subtitle}>
|
|
152
|
+
Your AI model is ready. Enter your email to receive your account details and access your digital twin.
|
|
153
|
+
</Text>
|
|
154
|
+
|
|
155
|
+
<View style={styles.emailContainer}>
|
|
156
|
+
<Text style={styles.emailLabel}>Email Address</Text>
|
|
157
|
+
<TextInput
|
|
158
|
+
style={styles.emailInput}
|
|
159
|
+
placeholder="Enter your email address"
|
|
160
|
+
placeholderTextColor="#999"
|
|
161
|
+
value={email}
|
|
162
|
+
onChangeText={setEmail}
|
|
163
|
+
keyboardType="email-address"
|
|
164
|
+
autoCapitalize="none"
|
|
165
|
+
autoCorrect={false}
|
|
166
|
+
autoComplete="email"
|
|
167
|
+
/>
|
|
168
|
+
<Text style={styles.emailHint}>
|
|
169
|
+
We'll send you login credentials and access to your AI persona
|
|
170
|
+
</Text>
|
|
171
|
+
</View>
|
|
172
|
+
|
|
173
|
+
<View style={styles.footer}>
|
|
174
|
+
<TouchableOpacity
|
|
175
|
+
style={styles.cancelButton}
|
|
176
|
+
onPress={onCancel}
|
|
177
|
+
>
|
|
178
|
+
<Text style={styles.cancelButtonText}>Cancel</Text>
|
|
179
|
+
</TouchableOpacity>
|
|
180
|
+
|
|
181
|
+
<TouchableOpacity
|
|
182
|
+
style={[
|
|
183
|
+
styles.completeButton,
|
|
184
|
+
!isValidEmail(email) && styles.completeButtonDisabled
|
|
185
|
+
]}
|
|
186
|
+
onPress={handleEmailSubmit}
|
|
187
|
+
disabled={!isValidEmail(email)}
|
|
188
|
+
>
|
|
189
|
+
<Text style={[
|
|
190
|
+
styles.completeButtonText,
|
|
191
|
+
!isValidEmail(email) && styles.completeButtonTextDisabled
|
|
192
|
+
]}>
|
|
193
|
+
Complete Setup
|
|
194
|
+
</Text>
|
|
195
|
+
</TouchableOpacity>
|
|
196
|
+
</View>
|
|
197
|
+
</>
|
|
90
198
|
)}
|
|
91
199
|
</View>
|
|
92
|
-
</
|
|
93
|
-
</
|
|
94
|
-
</
|
|
95
|
-
</
|
|
96
|
-
</
|
|
97
|
-
</
|
|
200
|
+
</SafeAreaView>
|
|
201
|
+
</View>
|
|
202
|
+
</TouchableWithoutFeedback>
|
|
203
|
+
</View>
|
|
204
|
+
</TouchableWithoutFeedback>
|
|
205
|
+
</KeyboardAvoidingView>
|
|
98
206
|
</Modal>
|
|
99
207
|
);
|
|
100
208
|
};
|
|
@@ -109,7 +217,7 @@ const styles = StyleSheet.create({
|
|
|
109
217
|
bottomSheet: {
|
|
110
218
|
backgroundColor: '#fff',
|
|
111
219
|
width: width,
|
|
112
|
-
height: height * 0.
|
|
220
|
+
height: height * 0.7,
|
|
113
221
|
borderTopLeftRadius: 24,
|
|
114
222
|
borderTopRightRadius: 24,
|
|
115
223
|
overflow: 'hidden',
|
|
@@ -150,6 +258,7 @@ const styles = StyleSheet.create({
|
|
|
150
258
|
color: COLORS.text.secondary,
|
|
151
259
|
textAlign: 'center',
|
|
152
260
|
marginBottom: 32,
|
|
261
|
+
lineHeight: 22,
|
|
153
262
|
},
|
|
154
263
|
progressContainer: {
|
|
155
264
|
width: '100%',
|
|
@@ -183,9 +292,37 @@ const styles = StyleSheet.create({
|
|
|
183
292
|
marginBottom: 32,
|
|
184
293
|
},
|
|
185
294
|
loadingText: {
|
|
295
|
+
fontSize: 16,
|
|
296
|
+
color: COLORS.text.primary,
|
|
297
|
+
marginLeft: 12,
|
|
298
|
+
fontWeight: '500',
|
|
299
|
+
},
|
|
300
|
+
emailContainer: {
|
|
301
|
+
width: '100%',
|
|
302
|
+
marginBottom: 32,
|
|
303
|
+
},
|
|
304
|
+
emailLabel: {
|
|
305
|
+
fontSize: 16,
|
|
306
|
+
fontWeight: '600',
|
|
307
|
+
color: COLORS.text.primary,
|
|
308
|
+
marginBottom: 8,
|
|
309
|
+
},
|
|
310
|
+
emailInput: {
|
|
311
|
+
width: '100%',
|
|
312
|
+
height: 48,
|
|
313
|
+
borderWidth: 1,
|
|
314
|
+
borderColor: '#E0E0E0',
|
|
315
|
+
borderRadius: 12,
|
|
316
|
+
paddingHorizontal: 16,
|
|
317
|
+
fontSize: 16,
|
|
318
|
+
color: COLORS.text.primary,
|
|
319
|
+
backgroundColor: '#F8F8F8',
|
|
320
|
+
},
|
|
321
|
+
emailHint: {
|
|
186
322
|
fontSize: 14,
|
|
187
323
|
color: COLORS.text.secondary,
|
|
188
|
-
|
|
324
|
+
marginTop: 8,
|
|
325
|
+
textAlign: 'center',
|
|
189
326
|
},
|
|
190
327
|
footer: {
|
|
191
328
|
flexDirection: 'row',
|
|
@@ -210,13 +347,17 @@ const styles = StyleSheet.create({
|
|
|
210
347
|
paddingVertical: 16,
|
|
211
348
|
paddingHorizontal: 32,
|
|
212
349
|
borderRadius: 16,
|
|
213
|
-
backgroundColor: '#
|
|
214
|
-
|
|
215
|
-
|
|
350
|
+
backgroundColor: '#000',
|
|
351
|
+
},
|
|
352
|
+
completeButtonDisabled: {
|
|
353
|
+
backgroundColor: '#E0E0E0',
|
|
216
354
|
},
|
|
217
355
|
completeButtonText: {
|
|
218
356
|
fontSize: 16,
|
|
219
357
|
fontWeight: '600',
|
|
220
|
-
color: '#
|
|
358
|
+
color: '#fff',
|
|
359
|
+
},
|
|
360
|
+
completeButtonTextDisabled: {
|
|
361
|
+
color: '#999',
|
|
221
362
|
},
|
|
222
363
|
});
|