@chem-po/firebase-native 0.0.51 → 0.0.53
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/adapter/auth.js +12 -5
- package/lib/commonjs/adapter/auth.js.map +1 -1
- package/lib/commonjs/adapter/db.js.map +1 -1
- package/lib/commonjs/adapter/index.js.map +1 -1
- package/lib/commonjs/adapter/storage.js.map +1 -1
- package/lib/commonjs/auth/functions.js.map +1 -1
- package/lib/commonjs/auth/index.js.map +1 -1
- package/lib/commonjs/components/AuthenticatorVerify.js +4 -2
- package/lib/commonjs/components/AuthenticatorVerify.js.map +1 -1
- package/lib/commonjs/components/FirebaseSignIn.js.map +1 -1
- package/lib/commonjs/components/PhoneVerify.js.map +1 -1
- package/lib/commonjs/components/TwoFactorAuthModal.js +3 -1
- package/lib/commonjs/components/TwoFactorAuthModal.js.map +1 -1
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/FirebaseContext.js.map +1 -1
- package/lib/commonjs/contexts/index.js.map +1 -1
- package/lib/commonjs/db/index.js.map +1 -1
- package/lib/commonjs/db/utils.js.map +1 -1
- package/lib/commonjs/hooks/backend.js.map +1 -1
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useAuthenticatorVerify.js +19 -13
- package/lib/commonjs/hooks/useAuthenticatorVerify.js.map +1 -1
- package/lib/commonjs/hooks/usePhoneVerify.js +1 -1
- package/lib/commonjs/hooks/usePhoneVerify.js.map +1 -1
- package/lib/commonjs/icons/Apple.js.map +1 -1
- package/lib/commonjs/icons/Google.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/storage/index.js.map +1 -1
- package/lib/commonjs/storage/utils.js.map +1 -1
- package/lib/commonjs/types/adapter.js.map +1 -1
- package/lib/commonjs/types/auth.js.map +1 -1
- package/lib/commonjs/types/db.js.map +1 -1
- package/lib/commonjs/types/functions.js.map +1 -1
- package/lib/commonjs/types/index.js.map +1 -1
- package/lib/commonjs/types/storage.js.map +1 -1
- package/lib/commonjs/utils/validation.js.map +1 -1
- package/lib/module/adapter/auth.js +13 -6
- package/lib/module/adapter/auth.js.map +1 -1
- package/lib/module/adapter/db.js.map +1 -1
- package/lib/module/adapter/index.js.map +1 -1
- package/lib/module/adapter/storage.js.map +1 -1
- package/lib/module/auth/functions.js.map +1 -1
- package/lib/module/auth/index.js.map +1 -1
- package/lib/module/components/AuthenticatorVerify.js +4 -2
- package/lib/module/components/AuthenticatorVerify.js.map +1 -1
- package/lib/module/components/FirebaseSignIn.js.map +1 -1
- package/lib/module/components/PhoneVerify.js.map +1 -1
- package/lib/module/components/TwoFactorAuthModal.js +3 -1
- package/lib/module/components/TwoFactorAuthModal.js.map +1 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/FirebaseContext.js.map +1 -1
- package/lib/module/contexts/index.js.map +1 -1
- package/lib/module/db/index.js.map +1 -1
- package/lib/module/db/utils.js.map +1 -1
- package/lib/module/hooks/backend.js.map +1 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useAuthenticatorVerify.js +20 -14
- package/lib/module/hooks/useAuthenticatorVerify.js.map +1 -1
- package/lib/module/hooks/usePhoneVerify.js +1 -1
- package/lib/module/hooks/usePhoneVerify.js.map +1 -1
- package/lib/module/icons/Apple.js.map +1 -1
- package/lib/module/icons/Google.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/storage/index.js.map +1 -1
- package/lib/module/storage/utils.js.map +1 -1
- package/lib/module/types/adapter.js.map +1 -1
- package/lib/module/types/auth.js.map +1 -1
- package/lib/module/types/db.js.map +1 -1
- package/lib/module/types/functions.js.map +1 -1
- package/lib/module/types/index.js.map +1 -1
- package/lib/module/types/storage.js.map +1 -1
- package/lib/module/utils/validation.js.map +1 -1
- package/lib/typescript/adapter/auth.d.ts.map +1 -1
- package/lib/typescript/components/AuthenticatorVerify.d.ts +4 -1
- package/lib/typescript/components/AuthenticatorVerify.d.ts.map +1 -1
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts +2 -1
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts.map +1 -1
- package/package.json +6 -21
- package/src/adapter/auth.ts +0 -556
- package/src/adapter/db.ts +0 -146
- package/src/adapter/index.ts +0 -32
- package/src/adapter/storage.ts +0 -58
- package/src/auth/functions.ts +0 -7
- package/src/auth/index.ts +0 -1
- package/src/components/AuthenticatorVerify.tsx +0 -75
- package/src/components/FirebaseSignIn.tsx +0 -234
- package/src/components/PhoneVerify.tsx +0 -115
- package/src/components/TwoFactorAuthModal.tsx +0 -198
- package/src/components/index.ts +0 -2
- package/src/contexts/FirebaseContext.tsx +0 -50
- package/src/contexts/index.ts +0 -1
- package/src/db/index.ts +0 -1
- package/src/db/utils.ts +0 -142
- package/src/hooks/backend.ts +0 -4
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useAuthenticatorVerify.ts +0 -45
- package/src/hooks/usePhoneVerify.ts +0 -87
- package/src/icons/Apple.tsx +0 -12
- package/src/icons/Google.tsx +0 -24
- package/src/index.ts +0 -9
- package/src/storage/index.ts +0 -1
- package/src/storage/utils.ts +0 -29
- package/src/types/adapter.ts +0 -13
- package/src/types/auth.ts +0 -13
- package/src/types/db.ts +0 -10
- package/src/types/functions.ts +0 -3
- package/src/types/index.ts +0 -29
- package/src/types/storage.ts +0 -3
- package/src/utils/validation.ts +0 -92
package/src/adapter/index.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { BackendAdapter, BaseAuthProvider } from '@chem-po/core'
|
|
2
|
-
import { FirebaseStorageTypes } from '@react-native-firebase/storage'
|
|
3
|
-
import { Auth, EmailPasswordLogin, User } from '../types/auth'
|
|
4
|
-
import { Firestore, FirestoreCursor } from '../types/db'
|
|
5
|
-
import { Functions } from '../types/functions'
|
|
6
|
-
import { Storage } from '../types/storage'
|
|
7
|
-
import { getFirebaseAuthAdapter } from './auth'
|
|
8
|
-
import { getFirebaseDatabaseAdapter } from './db'
|
|
9
|
-
import { getFirebaseStorageAdapter } from './storage'
|
|
10
|
-
|
|
11
|
-
export type FirebaseAdapter<AuthProvider extends BaseAuthProvider> = BackendAdapter<
|
|
12
|
-
AuthProvider,
|
|
13
|
-
User,
|
|
14
|
-
EmailPasswordLogin,
|
|
15
|
-
FirestoreCursor,
|
|
16
|
-
Blob,
|
|
17
|
-
FirebaseStorageTypes.FullMetadata
|
|
18
|
-
>
|
|
19
|
-
|
|
20
|
-
export const getFirebaseAdapter = <AuthProvider extends BaseAuthProvider>(
|
|
21
|
-
auth: Auth,
|
|
22
|
-
db: Firestore,
|
|
23
|
-
storage: Storage,
|
|
24
|
-
functions: Functions,
|
|
25
|
-
twoFactorRequired: boolean,
|
|
26
|
-
): FirebaseAdapter<AuthProvider> => {
|
|
27
|
-
return {
|
|
28
|
-
auth: getFirebaseAuthAdapter(auth, twoFactorRequired),
|
|
29
|
-
db: getFirebaseDatabaseAdapter(db, functions),
|
|
30
|
-
storage: getFirebaseStorageAdapter(storage),
|
|
31
|
-
}
|
|
32
|
-
}
|
package/src/adapter/storage.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { StorageAdapter, UploadedFileValue } from '@chem-po/core'
|
|
2
|
-
import {
|
|
3
|
-
deleteObject,
|
|
4
|
-
getDownloadURL,
|
|
5
|
-
getMetadata,
|
|
6
|
-
ref,
|
|
7
|
-
uploadBytesResumable,
|
|
8
|
-
} from '@react-native-firebase/storage'
|
|
9
|
-
import { Storage } from '../types/storage'
|
|
10
|
-
|
|
11
|
-
export const getFirebaseStorageAdapter = (storage: Storage): StorageAdapter<Blob, any> => ({
|
|
12
|
-
delete: async path => {
|
|
13
|
-
const storageRef = ref(storage, path)
|
|
14
|
-
await deleteObject(storageRef)
|
|
15
|
-
},
|
|
16
|
-
fetchObject: async path => {
|
|
17
|
-
const storageRef = ref(storage, path)
|
|
18
|
-
const url = await getDownloadURL(storageRef)
|
|
19
|
-
const response = await fetch(url)
|
|
20
|
-
return await response.blob()
|
|
21
|
-
},
|
|
22
|
-
fetchMetadata: async path => {
|
|
23
|
-
const storageRef = ref(storage, path)
|
|
24
|
-
return await getMetadata(storageRef)
|
|
25
|
-
},
|
|
26
|
-
getObjectUrl: async path => {
|
|
27
|
-
const storageRef = ref(storage, path)
|
|
28
|
-
return await getDownloadURL(storageRef)
|
|
29
|
-
},
|
|
30
|
-
upload: async (path, data, onUploadProgress) => {
|
|
31
|
-
const storageRef = ref(storage, path)
|
|
32
|
-
// Convert dataUrl to Blob
|
|
33
|
-
const blob = await fetch(data.dataUrl).then(res => res.blob())
|
|
34
|
-
const uploadTask = uploadBytesResumable(storageRef, blob)
|
|
35
|
-
return new Promise<UploadedFileValue>((resolve, reject) => {
|
|
36
|
-
uploadTask.on(
|
|
37
|
-
'state_changed',
|
|
38
|
-
snapshot => {
|
|
39
|
-
const progress = snapshot.bytesTransferred / snapshot.totalBytes
|
|
40
|
-
onUploadProgress({
|
|
41
|
-
loaded: snapshot.bytesTransferred,
|
|
42
|
-
total: snapshot.totalBytes,
|
|
43
|
-
percent: progress,
|
|
44
|
-
})
|
|
45
|
-
},
|
|
46
|
-
error => reject(error),
|
|
47
|
-
() => {
|
|
48
|
-
const fileValue: UploadedFileValue = {
|
|
49
|
-
filename: data.filename,
|
|
50
|
-
type: data.type,
|
|
51
|
-
storagePath: path,
|
|
52
|
-
}
|
|
53
|
-
resolve(fileValue)
|
|
54
|
-
},
|
|
55
|
-
)
|
|
56
|
-
})
|
|
57
|
-
},
|
|
58
|
-
})
|
package/src/auth/functions.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { FirebaseFunctionsTypes } from '@react-native-firebase/functions'
|
|
2
|
-
|
|
3
|
-
export const getThirdPartyAuthUrl = (functions: FirebaseFunctionsTypes.Module) =>
|
|
4
|
-
functions.httpsCallable('getThirdPartyAuthUrl')
|
|
5
|
-
|
|
6
|
-
export const getThirdPartyAuthToken = (functions: FirebaseFunctionsTypes.Module) =>
|
|
7
|
-
functions.httpsCallable('getThirdPartyAuthToken')
|
package/src/auth/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './functions'
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { LoadingButton, Txt } from '@chem-po/react-native'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { StyleSheet, TextInput, View } from 'react-native'
|
|
4
|
-
import { useAuthenticatorVerify } from '../hooks/useAuthenticatorVerify'
|
|
5
|
-
|
|
6
|
-
export const AuthenticatorVerify = () => {
|
|
7
|
-
const { code, setCode, verifying, error, handleVerify } = useAuthenticatorVerify()
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<View style={styles.wrapper}>
|
|
11
|
-
<View style={styles.container}>
|
|
12
|
-
<Txt style={styles.text}>Enter the code on your authenticator app:</Txt>
|
|
13
|
-
<TextInput
|
|
14
|
-
style={styles.input}
|
|
15
|
-
value={code}
|
|
16
|
-
onChangeText={setCode}
|
|
17
|
-
placeholder="Verification Code"
|
|
18
|
-
keyboardType="number-pad"
|
|
19
|
-
maxLength={6}
|
|
20
|
-
autoFocus
|
|
21
|
-
/>
|
|
22
|
-
{error ? <Txt style={styles.errorText}>{error}</Txt> : null}
|
|
23
|
-
<LoadingButton style={styles.button} onPress={handleVerify} disabled={verifying}>
|
|
24
|
-
<Txt style={styles.buttonText}>{verifying ? 'Verifying...' : 'Verify'}</Txt>
|
|
25
|
-
</LoadingButton>
|
|
26
|
-
</View>
|
|
27
|
-
</View>
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const styles = StyleSheet.create({
|
|
32
|
-
wrapper: {
|
|
33
|
-
flex: 1,
|
|
34
|
-
padding: 16,
|
|
35
|
-
},
|
|
36
|
-
container: {
|
|
37
|
-
flex: 1,
|
|
38
|
-
alignItems: 'center',
|
|
39
|
-
justifyContent: 'center',
|
|
40
|
-
gap: 16,
|
|
41
|
-
},
|
|
42
|
-
text: {
|
|
43
|
-
fontSize: 16,
|
|
44
|
-
textAlign: 'center',
|
|
45
|
-
marginBottom: 8,
|
|
46
|
-
},
|
|
47
|
-
input: {
|
|
48
|
-
width: '100%',
|
|
49
|
-
height: 48,
|
|
50
|
-
borderWidth: 1,
|
|
51
|
-
borderColor: '#ccc',
|
|
52
|
-
borderRadius: 8,
|
|
53
|
-
paddingHorizontal: 16,
|
|
54
|
-
fontSize: 16,
|
|
55
|
-
marginBottom: 8,
|
|
56
|
-
},
|
|
57
|
-
button: {
|
|
58
|
-
backgroundColor: '#007AFF',
|
|
59
|
-
paddingHorizontal: 24,
|
|
60
|
-
paddingVertical: 12,
|
|
61
|
-
borderRadius: 8,
|
|
62
|
-
minWidth: 200,
|
|
63
|
-
alignItems: 'center',
|
|
64
|
-
},
|
|
65
|
-
buttonText: {
|
|
66
|
-
color: 'white',
|
|
67
|
-
fontSize: 16,
|
|
68
|
-
fontWeight: '600',
|
|
69
|
-
},
|
|
70
|
-
errorText: {
|
|
71
|
-
color: 'red',
|
|
72
|
-
fontSize: 14,
|
|
73
|
-
marginBottom: 8,
|
|
74
|
-
},
|
|
75
|
-
})
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { useBackend } from '../hooks'
|
|
2
|
-
|
|
3
|
-
import { AppleAuthProvider, GoogleAuthProvider, ThirdPartyAuthProvider } from '@chem-po/core'
|
|
4
|
-
import { TextField, useBorderColor, useTextColor, useToast } from '@chem-po/react'
|
|
5
|
-
import { LoadingButton, StandaloneInput, Txt } from '@chem-po/react-native'
|
|
6
|
-
import { ButtonText } from '@chem-po/react-native/src/components/button/ButtonText'
|
|
7
|
-
import appleAuth from '@invertase/react-native-apple-authentication'
|
|
8
|
-
import React, { useCallback, useState } from 'react'
|
|
9
|
-
import { StyleSheet, View } from 'react-native'
|
|
10
|
-
import { Divider } from 'react-native-paper'
|
|
11
|
-
import SvgApple from '../icons/Apple'
|
|
12
|
-
import SvgGoogle from '../icons/Google'
|
|
13
|
-
|
|
14
|
-
const emailField: TextField = {
|
|
15
|
-
_type: 'text',
|
|
16
|
-
type: 'email',
|
|
17
|
-
placeholder: 'Email',
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const passwordField: TextField = {
|
|
21
|
-
_type: 'text',
|
|
22
|
-
type: 'password',
|
|
23
|
-
placeholder: 'Password',
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const thirdPartyInfo: Record<
|
|
27
|
-
ThirdPartyAuthProvider['name'],
|
|
28
|
-
{ icon: React.ReactNode; name: string }
|
|
29
|
-
> = {
|
|
30
|
-
google: { icon: <SvgGoogle width={24} />, name: 'Google' },
|
|
31
|
-
apple: { icon: <SvgApple width={24} />, name: 'Apple' },
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const ThirdPartyLogin = ({ provider }: { provider: GoogleAuthProvider | AppleAuthProvider }) => {
|
|
35
|
-
const { auth } = useBackend()
|
|
36
|
-
const { showError } = useToast()
|
|
37
|
-
|
|
38
|
-
const handleSignIn = useCallback(() => {
|
|
39
|
-
return auth.loginWithPopup(provider).catch(error => {
|
|
40
|
-
showError(error instanceof Error ? error.message : 'An unknown error occurred')
|
|
41
|
-
})
|
|
42
|
-
}, [auth, provider, showError])
|
|
43
|
-
|
|
44
|
-
const textColor = useTextColor(400)
|
|
45
|
-
return (
|
|
46
|
-
<View style={styles.row}>
|
|
47
|
-
<LoadingButton
|
|
48
|
-
color={textColor}
|
|
49
|
-
variant="outline"
|
|
50
|
-
style={[styles.googleLoginButton]}
|
|
51
|
-
onPress={handleSignIn}>
|
|
52
|
-
<View style={styles.googleLogin}>
|
|
53
|
-
{thirdPartyInfo[provider.name].icon}
|
|
54
|
-
<ButtonText
|
|
55
|
-
variant="outline"
|
|
56
|
-
color={textColor}>{`Log In with ${thirdPartyInfo[provider.name].name}`}</ButtonText>
|
|
57
|
-
</View>
|
|
58
|
-
</LoadingButton>
|
|
59
|
-
</View>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const EmailPasswordLogin = () => {
|
|
64
|
-
const [email, setEmail] = useState('')
|
|
65
|
-
const [password, setPassword] = useState('')
|
|
66
|
-
const [error, setError] = useState<string | null>(null)
|
|
67
|
-
const forgotPasswordTextColor = useTextColor(400)
|
|
68
|
-
|
|
69
|
-
const { auth } = useBackend()
|
|
70
|
-
const { showInfo } = useToast()
|
|
71
|
-
|
|
72
|
-
const handleLogin = async () => {
|
|
73
|
-
try {
|
|
74
|
-
await auth.loginWithPassword({ name: 'email' }, { email, password })
|
|
75
|
-
} catch (error) {
|
|
76
|
-
setError(error instanceof Error ? error.message : 'An unknown error occurred')
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return (
|
|
81
|
-
<View style={styles.column}>
|
|
82
|
-
<StandaloneInput field={emailField} onChange={setEmail} value={email} />
|
|
83
|
-
<StandaloneInput field={passwordField} onChange={setPassword} value={password} />
|
|
84
|
-
{error && (
|
|
85
|
-
<View style={styles.error}>
|
|
86
|
-
<Txt style={styles.errorText}>{error}</Txt>
|
|
87
|
-
</View>
|
|
88
|
-
)}
|
|
89
|
-
<View style={styles.row}>
|
|
90
|
-
<View style={styles.forgotPassword}>
|
|
91
|
-
<LoadingButton
|
|
92
|
-
color={forgotPasswordTextColor}
|
|
93
|
-
textStyle={styles.forgotPasswordButtonText}
|
|
94
|
-
style={styles.forgotPasswordButton}
|
|
95
|
-
size="sm"
|
|
96
|
-
variant="outline"
|
|
97
|
-
onPress={async () => {
|
|
98
|
-
// console.log('press')
|
|
99
|
-
showInfo('Visit our website to reset your password')
|
|
100
|
-
}}>
|
|
101
|
-
Forgot Password?
|
|
102
|
-
</LoadingButton>
|
|
103
|
-
</View>
|
|
104
|
-
<LoadingButton onPress={() => handleLogin()}>Sign In</LoadingButton>
|
|
105
|
-
</View>
|
|
106
|
-
</View>
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const ThirdPartyLogins = ({
|
|
111
|
-
appleProvider,
|
|
112
|
-
googleProvider,
|
|
113
|
-
}: {
|
|
114
|
-
appleProvider?: AppleAuthProvider
|
|
115
|
-
googleProvider?: GoogleAuthProvider
|
|
116
|
-
}) => {
|
|
117
|
-
const borderColor = useBorderColor()
|
|
118
|
-
const hasApple = appleProvider && appleAuth.isSupported
|
|
119
|
-
if (!googleProvider && !hasApple) return null
|
|
120
|
-
return (
|
|
121
|
-
<>
|
|
122
|
-
<Divider style={{ backgroundColor: borderColor, width: '100%' }} />
|
|
123
|
-
<View style={styles.thirdPartyLogins}>
|
|
124
|
-
{googleProvider ? <ThirdPartyLogin provider={googleProvider} /> : null}
|
|
125
|
-
{appleProvider && appleAuth.isSupported ? (
|
|
126
|
-
<ThirdPartyLogin provider={appleProvider} />
|
|
127
|
-
) : null}
|
|
128
|
-
</View>
|
|
129
|
-
</>
|
|
130
|
-
)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export const FirebaseSignIn = ({
|
|
134
|
-
googleProvider,
|
|
135
|
-
appleProvider,
|
|
136
|
-
}: {
|
|
137
|
-
googleProvider?: GoogleAuthProvider
|
|
138
|
-
appleProvider?: AppleAuthProvider
|
|
139
|
-
}) => {
|
|
140
|
-
return (
|
|
141
|
-
<View style={styles.signInContent}>
|
|
142
|
-
<EmailPasswordLogin />
|
|
143
|
-
<ThirdPartyLogins appleProvider={appleProvider} googleProvider={googleProvider} />
|
|
144
|
-
</View>
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const styles = StyleSheet.create({
|
|
149
|
-
container: {
|
|
150
|
-
flex: 1,
|
|
151
|
-
width: '100%',
|
|
152
|
-
justifyContent: 'center',
|
|
153
|
-
alignItems: 'center',
|
|
154
|
-
},
|
|
155
|
-
column: {
|
|
156
|
-
flexDirection: 'column',
|
|
157
|
-
gap: 10,
|
|
158
|
-
flex: 1,
|
|
159
|
-
width: '100%',
|
|
160
|
-
alignItems: 'center',
|
|
161
|
-
justifyContent: 'center',
|
|
162
|
-
},
|
|
163
|
-
thirdPartyLogins: {
|
|
164
|
-
flexDirection: 'column',
|
|
165
|
-
gap: 10,
|
|
166
|
-
flex: 1,
|
|
167
|
-
width: '100%',
|
|
168
|
-
alignItems: 'center',
|
|
169
|
-
justifyContent: 'center',
|
|
170
|
-
},
|
|
171
|
-
colorModeToggle: {
|
|
172
|
-
paddingVertical: 20,
|
|
173
|
-
},
|
|
174
|
-
signInContent: {
|
|
175
|
-
paddingVertical: 20,
|
|
176
|
-
paddingHorizontal: 20,
|
|
177
|
-
gap: 12,
|
|
178
|
-
justifyContent: 'center',
|
|
179
|
-
alignItems: 'center',
|
|
180
|
-
width: '100%',
|
|
181
|
-
},
|
|
182
|
-
forgotPasswordButton: {
|
|
183
|
-
borderWidth: 0,
|
|
184
|
-
backgroundColor: 'transparent',
|
|
185
|
-
},
|
|
186
|
-
forgotPasswordButtonText: {
|
|
187
|
-
fontSize: 14,
|
|
188
|
-
},
|
|
189
|
-
row: {
|
|
190
|
-
flexDirection: 'row',
|
|
191
|
-
justifyContent: 'space-between',
|
|
192
|
-
alignItems: 'center',
|
|
193
|
-
width: '100%',
|
|
194
|
-
},
|
|
195
|
-
forgotPassword: {
|
|
196
|
-
// flex: 1,
|
|
197
|
-
},
|
|
198
|
-
header: {
|
|
199
|
-
fontSize: 16,
|
|
200
|
-
opacity: 0.7,
|
|
201
|
-
fontWeight: 'bold',
|
|
202
|
-
},
|
|
203
|
-
infoText: {
|
|
204
|
-
fontSize: 16,
|
|
205
|
-
textAlign: 'center',
|
|
206
|
-
// fontFamily: fontFamilies.body.regular,
|
|
207
|
-
paddingBottom: 20,
|
|
208
|
-
},
|
|
209
|
-
logo: {
|
|
210
|
-
height: 50,
|
|
211
|
-
resizeMode: 'contain',
|
|
212
|
-
},
|
|
213
|
-
link: {
|
|
214
|
-
fontSize: 14,
|
|
215
|
-
// fontFamily: fontFamilies.body.regular,
|
|
216
|
-
textDecorationLine: 'underline',
|
|
217
|
-
fontWeight: 'semibold',
|
|
218
|
-
},
|
|
219
|
-
googleLogin: {
|
|
220
|
-
flexDirection: 'row',
|
|
221
|
-
alignItems: 'center',
|
|
222
|
-
justifyContent: 'center',
|
|
223
|
-
gap: 10,
|
|
224
|
-
width: '100%',
|
|
225
|
-
},
|
|
226
|
-
googleLoginButton: {
|
|
227
|
-
width: '100%',
|
|
228
|
-
},
|
|
229
|
-
error: {},
|
|
230
|
-
errorText: {
|
|
231
|
-
fontSize: 12,
|
|
232
|
-
color: 'red',
|
|
233
|
-
},
|
|
234
|
-
})
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { formatPhoneNumber, PhoneEnrollmentFactor } from '@chem-po/core'
|
|
2
|
-
import { useAuth, useBorderColor, useButtonColor, usePlaceholderColor, useTextColor } from '@chem-po/react'
|
|
3
|
-
import { CircularProgress, LoadingButton, Txt } from '@chem-po/react-native'
|
|
4
|
-
import React, { useMemo } from 'react'
|
|
5
|
-
import { StyleSheet, TextInput, View } from 'react-native'
|
|
6
|
-
import { usePhoneVerify } from '../hooks/usePhoneVerify'
|
|
7
|
-
|
|
8
|
-
// UI to send code and verify code
|
|
9
|
-
export const PhoneVerify = ({ factor }: { factor: PhoneEnrollmentFactor }) => {
|
|
10
|
-
const { handleVerify, verifying, error, code, setCode, sendCode, sendingCode } = usePhoneVerify(factor, true)
|
|
11
|
-
const { multiFactorVerification: twoFactorVerification, multiFactorLoading: loading } = useAuth()
|
|
12
|
-
const buttonBackgroundColor = useButtonColor()
|
|
13
|
-
const borderColor = useBorderColor()
|
|
14
|
-
const textColor = useTextColor()
|
|
15
|
-
const placeholderColor = usePlaceholderColor()
|
|
16
|
-
|
|
17
|
-
const verificationId = twoFactorVerification?.verificationId
|
|
18
|
-
const formattedPhoneNumber = useMemo(
|
|
19
|
-
() =>
|
|
20
|
-
Number.isNaN(Number(factor.phoneNumber))
|
|
21
|
-
? factor.phoneNumber
|
|
22
|
-
: formatPhoneNumber(factor.phoneNumber),
|
|
23
|
-
[factor.phoneNumber]
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
let body: React.ReactNode = null
|
|
27
|
-
|
|
28
|
-
if (sendingCode) {
|
|
29
|
-
body = (
|
|
30
|
-
<View style={styles.container}>
|
|
31
|
-
<CircularProgress size='large' />
|
|
32
|
-
<Txt style={styles.text}>Sending verification code...</Txt>
|
|
33
|
-
</View>
|
|
34
|
-
)
|
|
35
|
-
} else if (verificationId || verifying) {
|
|
36
|
-
body = (
|
|
37
|
-
<View style={styles.container}>
|
|
38
|
-
<Txt style={styles.text}>Enter the code sent to your phone:</Txt>
|
|
39
|
-
<TextInput
|
|
40
|
-
style={[styles.input, { borderColor, color: textColor }]}
|
|
41
|
-
value={code}
|
|
42
|
-
placeholderTextColor={placeholderColor}
|
|
43
|
-
onChangeText={setCode}
|
|
44
|
-
placeholder='Verification Code'
|
|
45
|
-
keyboardType='number-pad'
|
|
46
|
-
maxLength={6}
|
|
47
|
-
/>
|
|
48
|
-
{error ? <Txt style={styles.errorText}>{error}</Txt> : null}
|
|
49
|
-
<LoadingButton variant='solid' onPress={handleVerify} color={buttonBackgroundColor}>
|
|
50
|
-
Verify
|
|
51
|
-
</LoadingButton>
|
|
52
|
-
</View>
|
|
53
|
-
)
|
|
54
|
-
} else {
|
|
55
|
-
body = (
|
|
56
|
-
<View style={styles.container}>
|
|
57
|
-
<View style={styles.textContainer}>
|
|
58
|
-
<Txt style={styles.infoText}>We'll send a verification code to:</Txt>
|
|
59
|
-
<Txt style={styles.text}>{formattedPhoneNumber}</Txt>
|
|
60
|
-
</View>
|
|
61
|
-
<LoadingButton variant='solid' onPress={sendCode} disabled={loading} color={buttonBackgroundColor}>
|
|
62
|
-
Send Verification Code
|
|
63
|
-
</LoadingButton>
|
|
64
|
-
</View>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return <View style={styles.wrapper}>{body}</View>
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const styles = StyleSheet.create({
|
|
72
|
-
wrapper: {
|
|
73
|
-
flex: 1,
|
|
74
|
-
padding: 16,
|
|
75
|
-
},
|
|
76
|
-
container: {
|
|
77
|
-
flex: 1,
|
|
78
|
-
alignItems: 'center',
|
|
79
|
-
justifyContent: 'center',
|
|
80
|
-
gap: 8,
|
|
81
|
-
},
|
|
82
|
-
textContainer: {
|
|
83
|
-
alignItems: 'center',
|
|
84
|
-
justifyContent: 'center',
|
|
85
|
-
gap: 4,
|
|
86
|
-
},
|
|
87
|
-
infoText: {
|
|
88
|
-
fontSize: 15,
|
|
89
|
-
opacity: 0.8,
|
|
90
|
-
textAlign: 'center',
|
|
91
|
-
},
|
|
92
|
-
text: {
|
|
93
|
-
fontSize: 16,
|
|
94
|
-
textAlign: 'center',
|
|
95
|
-
marginBottom: 8,
|
|
96
|
-
},
|
|
97
|
-
input: {
|
|
98
|
-
width: '100%',
|
|
99
|
-
height: 48,
|
|
100
|
-
borderWidth: 1,
|
|
101
|
-
borderRadius: 8,
|
|
102
|
-
paddingHorizontal: 16,
|
|
103
|
-
fontSize: 16,
|
|
104
|
-
marginBottom: 8,
|
|
105
|
-
},
|
|
106
|
-
buttonText: {
|
|
107
|
-
fontSize: 16,
|
|
108
|
-
fontWeight: '600',
|
|
109
|
-
},
|
|
110
|
-
errorText: {
|
|
111
|
-
color: 'red',
|
|
112
|
-
fontSize: 14,
|
|
113
|
-
marginBottom: 8,
|
|
114
|
-
},
|
|
115
|
-
})
|