@@ -15,7 +15,7 @@ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
15
15
import OtpVerification from "./OtpVerification" ;
16
16
import { useTurnkey } from "../../hooks/use-turnkey" ;
17
17
import { FilterType , OtpType , authErrors } from "./constants" ;
18
- import type { WalletAccount } from "@turnkey/sdk-browser" ;
18
+ import type { TurnkeyApiTypes , WalletAccount } from "@turnkey/sdk-browser" ;
19
19
import { server } from "@turnkey/sdk-server" ;
20
20
import parsePhoneNumberFromString from "libphonenumber-js" ;
21
21
import { useRouter } from "next/navigation" ;
@@ -76,6 +76,8 @@ interface AuthProps {
76
76
facebookClientId ?: string ; // will default to NEXT_PUBLIC_FACEBOOK_CLIENT_ID
77
77
} ;
78
78
configOrder : string [ ] ;
79
+ emailCustomization ?: TurnkeyApiTypes [ "v1EmailCustomizationParams" ] ;
80
+ sendFromEmailAddress ?: string ;
79
81
customSmsMessage ?: string ;
80
82
customAccounts ?: WalletAccount [ ] ;
81
83
}
@@ -85,6 +87,8 @@ const Auth: React.FC<AuthProps> = ({
85
87
onError,
86
88
authConfig,
87
89
configOrder,
90
+ emailCustomization,
91
+ sendFromEmailAddress,
88
92
customSmsMessage,
89
93
customAccounts,
90
94
} ) => {
@@ -94,14 +98,14 @@ const Auth: React.FC<AuthProps> = ({
94
98
const [ phone , setPhone ] = useState < string > ( "" ) ;
95
99
const [ otpId , setOtpId ] = useState < string | null > ( null ) ;
96
100
const [ step , setStep ] = useState < string > ( "auth" ) ;
101
+ const [ loading , setLoading ] = useState < string | undefined > ( ) ;
97
102
const [ oauthLoading , setOauthLoading ] = useState < string > ( "" ) ;
98
103
const [ suborgId , setSuborgId ] = useState < string > ( "" ) ;
99
104
const [ passkeySignupScreen , setPasskeySignupScreen ] = useState ( false ) ;
100
105
const [ passkeyCreationScreen , setPasskeyCreationScreen ] = useState ( false ) ;
101
106
const [ passkeySignupError , setPasskeySignupError ] = useState ( "" ) ;
102
- const [ loading , setLoading ] = useState ( true ) ;
107
+ const [ componentReady , setComponentReady ] = useState ( false ) ;
103
108
const [ passkeyCreated , setPasskeyCreated ] = useState ( false ) ;
104
- const [ walletLoading , setWalletLoading ] = useState ( false ) ;
105
109
106
110
const handleResendCode = async ( ) => {
107
111
if ( step === OtpType . Email ) {
@@ -113,11 +117,11 @@ const Auth: React.FC<AuthProps> = ({
113
117
114
118
useEffect ( ( ) => {
115
119
if ( authIframeClient ) {
116
- setLoading ( false ) ;
120
+ setComponentReady ( true ) ;
117
121
}
118
122
} , [ authIframeClient ] ) ;
119
123
120
- if ( loading ) {
124
+ if ( ! componentReady ) {
121
125
return (
122
126
< div className = { styles . defaultLoader } >
123
127
< CircularProgress
@@ -198,13 +202,15 @@ const Auth: React.FC<AuthProps> = ({
198
202
authIframeClient ?. iframePublicKey ! ,
199
203
) ;
200
204
router . push ( "/dashboard" ) ;
201
- } catch {
205
+ } catch ( error ) {
202
206
setPasskeySignupError ( authErrors . passkey . timeoutOrNotAllowed ) ;
207
+ console . error ( "Error during passkey signup: " , error ) ;
203
208
}
204
209
} ;
205
210
206
211
const handleLoginWithPasskey = async ( ) => {
207
212
try {
213
+ setLoading ( "passkey" ) ;
208
214
await passkeyClient ?. loginWithPasskey (
209
215
SessionType . READ_WRITE ,
210
216
authIframeClient ! ,
@@ -213,6 +219,9 @@ const Auth: React.FC<AuthProps> = ({
213
219
router . push ( "/dashboard" ) ;
214
220
} catch ( error ) {
215
221
onError ( authErrors . passkey . loginFailed ) ;
222
+ console . error ( "Error during passkey login: " , error ) ;
223
+ } finally {
224
+ setLoading ( undefined ) ;
216
225
}
217
226
} ;
218
227
@@ -221,6 +230,7 @@ const Auth: React.FC<AuthProps> = ({
221
230
value : string ,
222
231
otpType : string ,
223
232
) => {
233
+ setLoading ( otpType ) ;
224
234
const createSuborgData : Record < string , any > = { } ;
225
235
if ( type === FilterType . Email ) createSuborgData . email = value ;
226
236
else if ( type === FilterType . PhoneNumber )
@@ -244,6 +254,8 @@ const Auth: React.FC<AuthProps> = ({
244
254
suborgID : suborgId ! ,
245
255
otpType,
246
256
contact : value ,
257
+ ...( emailCustomization && { emailCustomization } ) ,
258
+ ...( sendFromEmailAddress && { sendFromEmailAddress } ) ,
247
259
...( customSmsMessage && { customSmsMessage } ) ,
248
260
userIdentifier : authIframeClient ?. iframePublicKey ! ,
249
261
} ) ;
@@ -254,6 +266,7 @@ const Auth: React.FC<AuthProps> = ({
254
266
} else {
255
267
onError ( authErrors . otp . sendFailed ) ;
256
268
}
269
+ setLoading ( undefined ) ;
257
270
} ;
258
271
259
272
const handleOAuthLogin = async ( credential : string , providerName : string ) => {
@@ -290,7 +303,7 @@ const Auth: React.FC<AuthProps> = ({
290
303
} ;
291
304
292
305
const handleLoginWithWallet = async ( ) => {
293
- setWalletLoading ( true ) ;
306
+ setLoading ( "wallet" ) ;
294
307
try {
295
308
if ( ! walletClient ) {
296
309
throw new Error ( "Wallet client not initialized" ) ;
@@ -341,8 +354,9 @@ const Auth: React.FC<AuthProps> = ({
341
354
}
342
355
} catch ( error : any ) {
343
356
onError ( error . message || authErrors . wallet . loginFailed ) ;
357
+ console . error ( "Error during wallet login: " , error ) ;
344
358
} finally {
345
- setWalletLoading ( false ) ;
359
+ setLoading ( undefined ) ;
346
360
}
347
361
} ;
348
362
@@ -470,9 +484,17 @@ const Auth: React.FC<AuthProps> = ({
470
484
< button
471
485
className = { styles . authButton }
472
486
type = "submit"
473
- disabled = { ! isValidEmail ( email ) }
487
+ disabled = { ! isValidEmail ( email ) || loading === OtpType . Email }
474
488
>
475
- Continue
489
+ { loading === OtpType . Email ? (
490
+ < CircularProgress
491
+ size = { 24 }
492
+ thickness = { 4 }
493
+ className = { styles . buttonProgress || "" }
494
+ />
495
+ ) : (
496
+ "Continue"
497
+ ) }
476
498
</ button >
477
499
</ form >
478
500
) : null ;
@@ -491,9 +513,17 @@ const Auth: React.FC<AuthProps> = ({
491
513
< button
492
514
className = { styles . authButton }
493
515
type = "submit"
494
- disabled = { ! isValidPhone ( phone ) }
516
+ disabled = { ! isValidPhone ( phone ) || loading === OtpType . Sms }
495
517
>
496
- Continue
518
+ { loading === OtpType . Sms ? (
519
+ < CircularProgress
520
+ size = { 24 }
521
+ thickness = { 4 }
522
+ className = { styles . buttonProgress || "" }
523
+ />
524
+ ) : (
525
+ "Continue"
526
+ ) }
497
527
</ button >
498
528
</ form >
499
529
) : null ;
@@ -505,8 +535,17 @@ const Auth: React.FC<AuthProps> = ({
505
535
className = { styles . authButton }
506
536
type = "button"
507
537
onClick = { handleLoginWithPasskey }
538
+ disabled = { loading === "passkey" }
508
539
>
509
- Log in with passkey
540
+ { loading === "passkey" ? (
541
+ < CircularProgress
542
+ size = { 24 }
543
+ thickness = { 4 }
544
+ className = { styles . buttonProgress || "" }
545
+ />
546
+ ) : (
547
+ "Log in with passkey"
548
+ ) }
510
549
</ button >
511
550
< div
512
551
className = { styles . noPasskeyLink }
@@ -524,9 +563,9 @@ const Auth: React.FC<AuthProps> = ({
524
563
className = { styles . authButton }
525
564
type = "button"
526
565
onClick = { handleLoginWithWallet }
527
- disabled = { walletLoading }
566
+ disabled = { loading === "wallet" }
528
567
>
529
- { walletLoading ? (
568
+ { loading === "wallet" ? (
530
569
< CircularProgress
531
570
size = { 24 }
532
571
thickness = { 4 }
0 commit comments