signer-test-sdk-react 0.0.11 → 0.0.13
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/README.md +1 -1
- package/dist/src/AbstraxnProvider.d.ts +2 -5
- package/dist/src/AbstraxnProvider.js +550 -50
- package/dist/src/AbstraxnProvider.js.map +1 -1
- package/dist/src/WalletModal.css +1973 -23
- package/dist/src/WalletModal.d.ts +2 -1
- package/dist/src/WalletModal.js +200 -30
- package/dist/src/WalletModal.js.map +1 -1
- package/dist/src/chains.d.ts +55 -0
- package/dist/src/chains.js +221 -0
- package/dist/src/chains.js.map +1 -0
- package/dist/src/components/OnboardingUI/OnboardingUIReact.js +24 -3
- package/dist/src/components/OnboardingUI/OnboardingUIReact.js.map +1 -1
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +11 -2
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +266 -36
- package/dist/src/components/OnboardingUI/OnboardingUIWeb.js.map +1 -1
- package/dist/src/components/OnboardingUI/components/PasskeyButton.js +1 -1
- package/dist/src/components/OnboardingUI/components/PasskeyButton.js.map +1 -1
- package/dist/src/components/QRCode.d.ts +13 -0
- package/dist/src/components/QRCode.js +6 -0
- package/dist/src/components/QRCode.js.map +1 -0
- package/dist/src/components/WalletModal/components/ChainSelector.css +180 -0
- package/dist/src/components/WalletModal/components/ChainSelector.d.ts +10 -0
- package/dist/src/components/WalletModal/components/ChainSelector.js +34 -0
- package/dist/src/components/WalletModal/components/ChainSelector.js.map +1 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.css +133 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.d.ts +9 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.js +31 -0
- package/dist/src/components/WalletModal/components/ExportKeyModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.css +2 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.d.ts +11 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.js +18 -0
- package/dist/src/components/WalletModal/components/ExportWarningModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.css +160 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.d.ts +12 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.js +21 -0
- package/dist/src/components/WalletModal/components/ManageWalletModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.css +128 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.d.ts +17 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.js +10 -0
- package/dist/src/components/WalletModal/components/PreviewTransactionModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.css +101 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.d.ts +8 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.js +22 -0
- package/dist/src/components/WalletModal/components/ReceiveModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/SendModal.css +234 -0
- package/dist/src/components/WalletModal/components/SendModal.d.ts +18 -0
- package/dist/src/components/WalletModal/components/SendModal.js +127 -0
- package/dist/src/components/WalletModal/components/SendModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/SuccessModal.css +86 -0
- package/dist/src/components/WalletModal/components/SuccessModal.d.ts +13 -0
- package/dist/src/components/WalletModal/components/SuccessModal.js +8 -0
- package/dist/src/components/WalletModal/components/SuccessModal.js.map +1 -0
- package/dist/src/components/WalletModal/components/UserAvatar.d.ts +9 -0
- package/dist/src/components/WalletModal/components/UserAvatar.js +31 -0
- package/dist/src/components/WalletModal/components/UserAvatar.js.map +1 -0
- package/dist/src/components/WalletModal/components/index.d.ts +21 -0
- package/dist/src/components/WalletModal/components/index.js +13 -0
- package/dist/src/components/WalletModal/components/index.js.map +1 -0
- package/dist/src/components/WalletModal/hooks/index.d.ts +6 -0
- package/dist/src/components/WalletModal/hooks/index.js +7 -0
- package/dist/src/components/WalletModal/hooks/index.js.map +1 -0
- package/dist/src/components/WalletModal/hooks/useAddressValidation.d.ts +4 -0
- package/dist/src/components/WalletModal/hooks/useAddressValidation.js +17 -0
- package/dist/src/components/WalletModal/hooks/useAddressValidation.js.map +1 -0
- package/dist/src/components/WalletModal/hooks/useAmountValidation.d.ts +4 -0
- package/dist/src/components/WalletModal/hooks/useAmountValidation.js +29 -0
- package/dist/src/components/WalletModal/hooks/useAmountValidation.js.map +1 -0
- package/dist/src/components/WalletModal/hooks/useSendTransaction.d.ts +20 -0
- package/dist/src/components/WalletModal/hooks/useSendTransaction.js +55 -0
- package/dist/src/components/WalletModal/hooks/useSendTransaction.js.map +1 -0
- package/dist/src/components/WalletModal/index.d.ts +5 -0
- package/dist/src/components/WalletModal/index.js +7 -0
- package/dist/src/components/WalletModal/index.js.map +1 -0
- package/dist/src/components/WalletModal/utils/addressUtils.d.ts +19 -0
- package/dist/src/components/WalletModal/utils/addressUtils.js +62 -0
- package/dist/src/components/WalletModal/utils/addressUtils.js.map +1 -0
- package/dist/src/components/WalletModal/utils/formatUtils.d.ts +20 -0
- package/dist/src/components/WalletModal/utils/formatUtils.js +47 -0
- package/dist/src/components/WalletModal/utils/formatUtils.js.map +1 -0
- package/dist/src/components/WalletModal/utils/index.d.ts +5 -0
- package/dist/src/components/WalletModal/utils/index.js +6 -0
- package/dist/src/components/WalletModal/utils/index.js.map +1 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +29 -0
- package/dist/src/wagmiConfig.js +6 -2
- package/dist/src/wagmiConfig.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
|
@@ -590,6 +590,46 @@ const ONBOARDING_UI_STYLES = `
|
|
|
590
590
|
width: 100%;
|
|
591
591
|
}
|
|
592
592
|
|
|
593
|
+
/* Hide social buttons when OTP screen is visible - using class for better browser support */
|
|
594
|
+
.onboarding-card.onboarding-otp-active .onboarding-button-google,
|
|
595
|
+
.onboarding-card.onboarding-otp-active .onboarding-button-social,
|
|
596
|
+
.onboarding-card.onboarding-otp-active .onboarding-social-grid,
|
|
597
|
+
.onboarding-card.onboarding-otp-active .onboarding-divider:not(.onboarding-otp-divider),
|
|
598
|
+
.onboarding-card.onboarding-otp-active .onboarding-button-passkey,
|
|
599
|
+
.onboarding-card.onboarding-otp-active .onboarding-passkey-signup-link,
|
|
600
|
+
.onboarding-card.onboarding-otp-active .onboarding-passkey-divider,
|
|
601
|
+
.onboarding-card.onboarding-otp-active .onboarding-form:not(.onboarding-otp-form),
|
|
602
|
+
.onboarding-card.onboarding-otp-active .onboarding-input-group:not(.onboarding-otp-inputs-container) {
|
|
603
|
+
display: none !important;
|
|
604
|
+
visibility: hidden !important;
|
|
605
|
+
opacity: 0 !important;
|
|
606
|
+
height: 0 !important;
|
|
607
|
+
margin: 0 !important;
|
|
608
|
+
padding: 0 !important;
|
|
609
|
+
overflow: hidden !important;
|
|
610
|
+
pointer-events: none !important;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/* Fallback using :has() for modern browsers */
|
|
614
|
+
@supports selector(:has(*)) {
|
|
615
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-button-google,
|
|
616
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-button-social,
|
|
617
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-social-grid,
|
|
618
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-divider:not(.onboarding-otp-divider),
|
|
619
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-button-passkey,
|
|
620
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-passkey-signup-link,
|
|
621
|
+
.onboarding-card:has(.onboarding-otp-verification) .onboarding-passkey-divider {
|
|
622
|
+
display: none !important;
|
|
623
|
+
visibility: hidden !important;
|
|
624
|
+
opacity: 0 !important;
|
|
625
|
+
height: 0 !important;
|
|
626
|
+
margin: 0 !important;
|
|
627
|
+
padding: 0 !important;
|
|
628
|
+
overflow: hidden !important;
|
|
629
|
+
pointer-events: none !important;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
593
633
|
.onboarding-social-icon {
|
|
594
634
|
width: 20px;
|
|
595
635
|
height: 20px;
|
|
@@ -856,13 +896,17 @@ const ONBOARDING_UI_STYLES = `
|
|
|
856
896
|
color: #b91c1c;
|
|
857
897
|
}
|
|
858
898
|
|
|
859
|
-
.onboarding-otp-resend-link:disabled
|
|
899
|
+
.onboarding-otp-resend-link:disabled,
|
|
900
|
+
.onboarding-otp-resend-link-disabled {
|
|
860
901
|
color: #9ca3af;
|
|
861
902
|
cursor: not-allowed;
|
|
862
903
|
text-decoration: none;
|
|
904
|
+
pointer-events: none;
|
|
905
|
+
opacity: 0.6;
|
|
863
906
|
}
|
|
864
907
|
|
|
865
|
-
.onboarding-theme-dark .onboarding-otp-resend-link:disabled
|
|
908
|
+
.onboarding-theme-dark .onboarding-otp-resend-link:disabled,
|
|
909
|
+
.onboarding-theme-dark .onboarding-otp-resend-link-disabled {
|
|
866
910
|
color: #6b7280;
|
|
867
911
|
}
|
|
868
912
|
|
|
@@ -905,7 +949,8 @@ const ONBOARDING_UI_STYLES = `
|
|
|
905
949
|
font-size: 14px;
|
|
906
950
|
font-weight: 500;
|
|
907
951
|
margin-top: 12px;
|
|
908
|
-
display:
|
|
952
|
+
display: block;
|
|
953
|
+
text-align: center;
|
|
909
954
|
transition: color 0.15s ease;
|
|
910
955
|
}
|
|
911
956
|
|
|
@@ -943,6 +988,7 @@ export class OnboardingUIWeb {
|
|
|
943
988
|
emailInput = null;
|
|
944
989
|
otpInput = null;
|
|
945
990
|
otpInputs = [];
|
|
991
|
+
autoSubmitEnabled = true; // Flag to control auto-submit after failed attempts
|
|
946
992
|
emailForm = null;
|
|
947
993
|
continueButton = null;
|
|
948
994
|
emailArrowButton = null;
|
|
@@ -970,6 +1016,7 @@ export class OnboardingUIWeb {
|
|
|
970
1016
|
loading = false;
|
|
971
1017
|
activeButton = null;
|
|
972
1018
|
resendCooldown = 0;
|
|
1019
|
+
resendCooldownTimer = null;
|
|
973
1020
|
externalWalletsEnabled = false;
|
|
974
1021
|
constructor(config, externalWalletsEnabled = false) {
|
|
975
1022
|
this.externalWalletsEnabled = externalWalletsEnabled;
|
|
@@ -1019,16 +1066,40 @@ export class OnboardingUIWeb {
|
|
|
1019
1066
|
const params = new URLSearchParams(window.location.search);
|
|
1020
1067
|
const success = params.get('success');
|
|
1021
1068
|
const error = params.get('error');
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1069
|
+
const accessToken = params.get('accessToken');
|
|
1070
|
+
const provider = params.get('provider') || params.get('authProvider');
|
|
1071
|
+
// Helper to extract provider from accessToken JWT
|
|
1072
|
+
const getAuthProviderFromToken = (token) => {
|
|
1073
|
+
try {
|
|
1074
|
+
const base64Url = token.split('.')[1];
|
|
1075
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
1076
|
+
const jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {
|
|
1077
|
+
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
1078
|
+
}).join(''));
|
|
1079
|
+
const payload = JSON.parse(jsonPayload);
|
|
1080
|
+
return (payload.authProvider || payload.provider || '').toLowerCase();
|
|
1030
1081
|
}
|
|
1031
|
-
|
|
1082
|
+
catch (e) {
|
|
1083
|
+
return null;
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
// Detect OAuth callback: check for provider in URL or extract from accessToken
|
|
1087
|
+
let detectedProvider = provider;
|
|
1088
|
+
if (!detectedProvider && accessToken) {
|
|
1089
|
+
detectedProvider = getAuthProviderFromToken(accessToken);
|
|
1090
|
+
}
|
|
1091
|
+
const isOAuthCallback = detectedProvider && (detectedProvider === 'google' || detectedProvider === 'discord' || detectedProvider === 'twitter' || detectedProvider === 'x');
|
|
1092
|
+
const hasOAuthParams = isOAuthCallback || (success === 'true' && !!accessToken);
|
|
1093
|
+
// If success=true and it's an OAuth callback (Google, Discord, Twitter), show loading modal with header and footer
|
|
1094
|
+
if (success === 'true' && hasOAuthParams) {
|
|
1095
|
+
// Show loading modal immediately - it creates its own overlay
|
|
1096
|
+
// Use requestAnimationFrame + setTimeout to ensure DOM is ready
|
|
1097
|
+
requestAnimationFrame(() => {
|
|
1098
|
+
setTimeout(() => {
|
|
1099
|
+
// Directly show loading modal - it will create its own overlay with header and footer
|
|
1100
|
+
this.showLoadingModal();
|
|
1101
|
+
}, 100);
|
|
1102
|
+
});
|
|
1032
1103
|
return;
|
|
1033
1104
|
}
|
|
1034
1105
|
// Check login source to decide if we should handle this (for errors)
|
|
@@ -1187,6 +1258,7 @@ export class OnboardingUIWeb {
|
|
|
1187
1258
|
}
|
|
1188
1259
|
/**
|
|
1189
1260
|
* Show loading screen as a modal overlay (for inline components)
|
|
1261
|
+
* Public method to allow external access
|
|
1190
1262
|
*/
|
|
1191
1263
|
showLoadingModal() {
|
|
1192
1264
|
// Hide any other modals that might be showing (wallet selection, etc.)
|
|
@@ -1233,10 +1305,10 @@ export class OnboardingUIWeb {
|
|
|
1233
1305
|
box-sizing: border-box;
|
|
1234
1306
|
`,
|
|
1235
1307
|
});
|
|
1236
|
-
// Header with logo
|
|
1308
|
+
// Header with logo and title
|
|
1237
1309
|
const header = this.createElement('div', {
|
|
1238
1310
|
className: 'onboarding-header',
|
|
1239
|
-
style: 'display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%;',
|
|
1311
|
+
style: 'display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; margin-bottom: 32px;',
|
|
1240
1312
|
});
|
|
1241
1313
|
const logoSection = this.createElement('div', { className: 'onboarding-logo-section' });
|
|
1242
1314
|
if (this.config.logo) {
|
|
@@ -1250,6 +1322,22 @@ export class OnboardingUIWeb {
|
|
|
1250
1322
|
logoSection.appendChild(logoContainer);
|
|
1251
1323
|
}
|
|
1252
1324
|
header.appendChild(logoSection);
|
|
1325
|
+
// Add title
|
|
1326
|
+
const title = this.createElement('h1', {
|
|
1327
|
+
className: 'onboarding-title',
|
|
1328
|
+
textContent: this.config.onboardTitle || 'Sign in',
|
|
1329
|
+
style: `
|
|
1330
|
+
font-size: 24px;
|
|
1331
|
+
font-weight: 600;
|
|
1332
|
+
margin: 0;
|
|
1333
|
+
color: ${this.config.theme === 'dark' ? '#ffffff' : '#111827'};
|
|
1334
|
+
text-align: center;
|
|
1335
|
+
margin-bottom: 0;
|
|
1336
|
+
letter-spacing: -0.01em;
|
|
1337
|
+
line-height: 1.4;
|
|
1338
|
+
`,
|
|
1339
|
+
});
|
|
1340
|
+
header.appendChild(title);
|
|
1253
1341
|
loadingCard.appendChild(header);
|
|
1254
1342
|
// Spinner
|
|
1255
1343
|
const spinnerColor = this.config.theme === 'dark' ? '#9ca3af' : '#111827';
|
|
@@ -1342,10 +1430,21 @@ export class OnboardingUIWeb {
|
|
|
1342
1430
|
document.body.appendChild(loadingModalOverlay);
|
|
1343
1431
|
}
|
|
1344
1432
|
else {
|
|
1433
|
+
// Ensure modal is visible
|
|
1345
1434
|
loadingModalOverlay.style.display = 'flex';
|
|
1435
|
+
loadingModalOverlay.style.visibility = 'visible';
|
|
1436
|
+
loadingModalOverlay.style.opacity = '1';
|
|
1437
|
+
loadingModalOverlay.style.zIndex = '9999999';
|
|
1346
1438
|
}
|
|
1347
1439
|
// Prevent body scroll
|
|
1348
1440
|
document.body.style.overflow = 'hidden';
|
|
1441
|
+
// Force visibility (defensive check)
|
|
1442
|
+
if (loadingModalOverlay) {
|
|
1443
|
+
loadingModalOverlay.style.display = 'flex';
|
|
1444
|
+
loadingModalOverlay.style.visibility = 'visible';
|
|
1445
|
+
loadingModalOverlay.style.opacity = '1';
|
|
1446
|
+
loadingModalOverlay.style.zIndex = '9999999';
|
|
1447
|
+
}
|
|
1349
1448
|
}
|
|
1350
1449
|
/**
|
|
1351
1450
|
* Hide loading modal overlay
|
|
@@ -1354,6 +1453,8 @@ export class OnboardingUIWeb {
|
|
|
1354
1453
|
const loadingModalOverlay = document.getElementById('onboarding-loading-modal-overlay');
|
|
1355
1454
|
if (loadingModalOverlay) {
|
|
1356
1455
|
loadingModalOverlay.style.display = 'none';
|
|
1456
|
+
loadingModalOverlay.style.visibility = 'hidden';
|
|
1457
|
+
loadingModalOverlay.style.opacity = '0';
|
|
1357
1458
|
document.body.style.overflow = '';
|
|
1358
1459
|
}
|
|
1359
1460
|
}
|
|
@@ -2422,12 +2523,11 @@ export class OnboardingUIWeb {
|
|
|
2422
2523
|
}
|
|
2423
2524
|
}
|
|
2424
2525
|
/**
|
|
2425
|
-
*
|
|
2526
|
+
* Hide all login-related elements (social buttons, passkey, etc.)
|
|
2527
|
+
* This ensures they stay hidden on the OTP screen
|
|
2528
|
+
* Made public so it can be called from AbstraxnProvider
|
|
2426
2529
|
*/
|
|
2427
|
-
|
|
2428
|
-
if (!this.rootElement)
|
|
2429
|
-
return;
|
|
2430
|
-
// Hide the email form and all login-related elements
|
|
2530
|
+
hideLoginElements() {
|
|
2431
2531
|
if (this.emailForm) {
|
|
2432
2532
|
this.emailForm.style.display = 'none';
|
|
2433
2533
|
}
|
|
@@ -2470,6 +2570,15 @@ export class OnboardingUIWeb {
|
|
|
2470
2570
|
if (this.footer) {
|
|
2471
2571
|
this.footer.style.display = 'none';
|
|
2472
2572
|
}
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Show OTP verification screen
|
|
2576
|
+
*/
|
|
2577
|
+
showOtpInput() {
|
|
2578
|
+
if (!this.rootElement)
|
|
2579
|
+
return;
|
|
2580
|
+
// Hide the email form and all login-related elements
|
|
2581
|
+
this.hideLoginElements();
|
|
2473
2582
|
// Create OTP verification screen
|
|
2474
2583
|
this.createOtpVerificationScreen();
|
|
2475
2584
|
}
|
|
@@ -2488,6 +2597,8 @@ export class OnboardingUIWeb {
|
|
|
2488
2597
|
const card = this.rootElement.querySelector('.onboarding-card');
|
|
2489
2598
|
if (!card)
|
|
2490
2599
|
return;
|
|
2600
|
+
// Add class to card to indicate OTP screen is active (for CSS targeting)
|
|
2601
|
+
card.classList.add('onboarding-otp-active');
|
|
2491
2602
|
// Create OTP verification container
|
|
2492
2603
|
this.otpVerificationScreen = this.createElement('div', {
|
|
2493
2604
|
className: 'onboarding-otp-verification',
|
|
@@ -2573,7 +2684,15 @@ export class OnboardingUIWeb {
|
|
|
2573
2684
|
const resendLink = resendSection.querySelector('#otp-resend-link');
|
|
2574
2685
|
if (resendLink) {
|
|
2575
2686
|
this.resendButton = resendLink;
|
|
2576
|
-
resendLink.addEventListener('click', () =>
|
|
2687
|
+
resendLink.addEventListener('click', (e) => {
|
|
2688
|
+
e.preventDefault();
|
|
2689
|
+
e.stopPropagation();
|
|
2690
|
+
// Prevent click if cooldown is active
|
|
2691
|
+
if (this.resendCooldown > 0) {
|
|
2692
|
+
return;
|
|
2693
|
+
}
|
|
2694
|
+
this.handleResendOtp();
|
|
2695
|
+
});
|
|
2577
2696
|
}
|
|
2578
2697
|
// Footer (add to OTP screen as well)
|
|
2579
2698
|
if (this.config.showFooter) {
|
|
@@ -2631,11 +2750,24 @@ export class OnboardingUIWeb {
|
|
|
2631
2750
|
}
|
|
2632
2751
|
// Append to card
|
|
2633
2752
|
card.appendChild(this.otpVerificationScreen);
|
|
2753
|
+
// Ensure login elements are hidden when OTP screen is created
|
|
2754
|
+
// This is critical to prevent social buttons from showing
|
|
2755
|
+
this.hideLoginElements();
|
|
2756
|
+
// Also ensure they stay hidden after DOM updates
|
|
2757
|
+
setTimeout(() => {
|
|
2758
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
2759
|
+
this.hideLoginElements();
|
|
2760
|
+
}
|
|
2761
|
+
}, 0);
|
|
2634
2762
|
// Focus first input
|
|
2635
2763
|
setTimeout(() => {
|
|
2636
2764
|
if (this.otpInputs[0]) {
|
|
2637
2765
|
this.otpInputs[0].focus();
|
|
2638
2766
|
}
|
|
2767
|
+
// Final check to ensure social buttons are hidden
|
|
2768
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
2769
|
+
this.hideLoginElements();
|
|
2770
|
+
}
|
|
2639
2771
|
}, 100);
|
|
2640
2772
|
// Start resend cooldown
|
|
2641
2773
|
this.startResendCooldown();
|
|
@@ -2672,12 +2804,23 @@ export class OnboardingUIWeb {
|
|
|
2672
2804
|
if (index < 5 && this.otpInputs[index + 1]) {
|
|
2673
2805
|
this.otpInputs[index + 1].focus();
|
|
2674
2806
|
}
|
|
2675
|
-
//
|
|
2807
|
+
// Re-enable auto-submit when user starts typing (clears previous error state)
|
|
2808
|
+
if (!this.autoSubmitEnabled) {
|
|
2809
|
+
this.autoSubmitEnabled = true;
|
|
2810
|
+
this.setError(null); // Clear any previous error
|
|
2811
|
+
}
|
|
2676
2812
|
}
|
|
2677
2813
|
else {
|
|
2678
2814
|
input.value = '';
|
|
2679
2815
|
}
|
|
2680
2816
|
this.updateOtpValue();
|
|
2817
|
+
// Auto-submit when 6 digits are entered (only if auto-submit is enabled)
|
|
2818
|
+
if (this.otp.length === 6 && this.autoSubmitEnabled && !this.loading) {
|
|
2819
|
+
// Small delay to ensure the last digit is properly set
|
|
2820
|
+
setTimeout(() => {
|
|
2821
|
+
this.handleOtpVerify();
|
|
2822
|
+
}, 100);
|
|
2823
|
+
}
|
|
2681
2824
|
}
|
|
2682
2825
|
/**
|
|
2683
2826
|
* Handle OTP keydown - backspace to go to previous field
|
|
@@ -2706,7 +2849,13 @@ export class OnboardingUIWeb {
|
|
|
2706
2849
|
this.otpInputs[lastFilledIndex].focus();
|
|
2707
2850
|
}
|
|
2708
2851
|
this.updateOtpValue();
|
|
2709
|
-
//
|
|
2852
|
+
// Auto-submit when 6 digits are pasted (only if auto-submit is enabled)
|
|
2853
|
+
if (this.otp.length === 6 && this.autoSubmitEnabled && !this.loading) {
|
|
2854
|
+
// Small delay to ensure all digits are properly set
|
|
2855
|
+
setTimeout(() => {
|
|
2856
|
+
this.handleOtpVerify();
|
|
2857
|
+
}, 100);
|
|
2858
|
+
}
|
|
2710
2859
|
}
|
|
2711
2860
|
/**
|
|
2712
2861
|
* Update OTP value from input fields
|
|
@@ -2736,7 +2885,9 @@ export class OnboardingUIWeb {
|
|
|
2736
2885
|
this.config.onLoginSuccess?.(result);
|
|
2737
2886
|
}
|
|
2738
2887
|
else {
|
|
2739
|
-
|
|
2888
|
+
// Use the error message from the API response, fallback to generic message only if not provided
|
|
2889
|
+
const errorMessage = result.error || 'Invalid verification code';
|
|
2890
|
+
throw new Error(errorMessage);
|
|
2740
2891
|
}
|
|
2741
2892
|
}
|
|
2742
2893
|
else if (this.config.emailOtpEndpoint) {
|
|
@@ -2752,7 +2903,9 @@ export class OnboardingUIWeb {
|
|
|
2752
2903
|
this.config.onLoginSuccess?.({ token: data.token });
|
|
2753
2904
|
}
|
|
2754
2905
|
else {
|
|
2755
|
-
|
|
2906
|
+
// Use the error message from the API response, fallback to generic message only if not provided
|
|
2907
|
+
const errorMessage = data.message || data.error || 'Invalid verification code';
|
|
2908
|
+
throw new Error(errorMessage);
|
|
2756
2909
|
}
|
|
2757
2910
|
}
|
|
2758
2911
|
}
|
|
@@ -2760,6 +2913,26 @@ export class OnboardingUIWeb {
|
|
|
2760
2913
|
const errorMessage = err instanceof Error ? err.message : 'An error occurred';
|
|
2761
2914
|
this.setError(errorMessage);
|
|
2762
2915
|
this.config.onLoginError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
2916
|
+
// Disable auto-submit after failed attempt
|
|
2917
|
+
this.autoSubmitEnabled = false;
|
|
2918
|
+
// Ensure social buttons and login elements remain hidden on OTP screen when error occurs
|
|
2919
|
+
// This prevents them from appearing when an OTP error is shown
|
|
2920
|
+
if (this.otpVerificationScreen) {
|
|
2921
|
+
// Immediately hide login elements
|
|
2922
|
+
this.hideLoginElements();
|
|
2923
|
+
// Also use setTimeout to ensure they stay hidden after any potential re-renders
|
|
2924
|
+
setTimeout(() => {
|
|
2925
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
2926
|
+
this.hideLoginElements();
|
|
2927
|
+
}
|
|
2928
|
+
}, 0);
|
|
2929
|
+
// Additional check after a short delay to catch any late re-renders
|
|
2930
|
+
setTimeout(() => {
|
|
2931
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
2932
|
+
this.hideLoginElements();
|
|
2933
|
+
}
|
|
2934
|
+
}, 100);
|
|
2935
|
+
}
|
|
2763
2936
|
// Clear OTP inputs on error
|
|
2764
2937
|
this.otpInputs.forEach(input => {
|
|
2765
2938
|
input.value = '';
|
|
@@ -2781,6 +2954,8 @@ export class OnboardingUIWeb {
|
|
|
2781
2954
|
if (this.resendCooldown > 0) {
|
|
2782
2955
|
return;
|
|
2783
2956
|
}
|
|
2957
|
+
// Re-enable auto-submit when resending OTP
|
|
2958
|
+
this.autoSubmitEnabled = true;
|
|
2784
2959
|
this.setError(null);
|
|
2785
2960
|
this.setLoading(true, 'email');
|
|
2786
2961
|
try {
|
|
@@ -2824,20 +2999,42 @@ export class OnboardingUIWeb {
|
|
|
2824
2999
|
* Start resend cooldown timer
|
|
2825
3000
|
*/
|
|
2826
3001
|
startResendCooldown() {
|
|
3002
|
+
// Clear any existing cooldown timer
|
|
3003
|
+
if (this.resendCooldownTimer) {
|
|
3004
|
+
clearInterval(this.resendCooldownTimer);
|
|
3005
|
+
}
|
|
2827
3006
|
this.resendCooldown = 60; // 60 seconds cooldown
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
3007
|
+
// Update UI immediately
|
|
3008
|
+
if (this.resendButton) {
|
|
3009
|
+
this.resendButton.textContent = `Resend (${this.resendCooldown}s)`;
|
|
3010
|
+
this.resendButton.classList.add('onboarding-otp-resend-link-disabled');
|
|
3011
|
+
this.resendButton.style.pointerEvents = 'none';
|
|
3012
|
+
this.resendButton.style.cursor = 'not-allowed';
|
|
3013
|
+
this.resendButton.style.opacity = '0.6';
|
|
3014
|
+
}
|
|
3015
|
+
// Start countdown timer
|
|
3016
|
+
this.resendCooldownTimer = setInterval(() => {
|
|
3017
|
+
if (this.resendCooldown > 0) {
|
|
2832
3018
|
this.resendCooldown--;
|
|
2833
|
-
|
|
3019
|
+
if (this.resendButton) {
|
|
3020
|
+
this.resendButton.textContent = `Resend (${this.resendCooldown}s)`;
|
|
3021
|
+
}
|
|
2834
3022
|
}
|
|
2835
|
-
else
|
|
2836
|
-
|
|
2837
|
-
this.
|
|
3023
|
+
else {
|
|
3024
|
+
// Cooldown complete, enable resend
|
|
3025
|
+
if (this.resendCooldownTimer) {
|
|
3026
|
+
clearInterval(this.resendCooldownTimer);
|
|
3027
|
+
this.resendCooldownTimer = null;
|
|
3028
|
+
}
|
|
3029
|
+
if (this.resendButton) {
|
|
3030
|
+
this.resendButton.textContent = 'Resend';
|
|
3031
|
+
this.resendButton.classList.remove('onboarding-otp-resend-link-disabled');
|
|
3032
|
+
this.resendButton.style.pointerEvents = 'auto';
|
|
3033
|
+
this.resendButton.style.cursor = 'pointer';
|
|
3034
|
+
this.resendButton.style.opacity = '1';
|
|
3035
|
+
}
|
|
2838
3036
|
}
|
|
2839
|
-
};
|
|
2840
|
-
updateCooldown();
|
|
3037
|
+
}, 1000);
|
|
2841
3038
|
}
|
|
2842
3039
|
/**
|
|
2843
3040
|
* Set error message
|
|
@@ -2854,6 +3051,24 @@ export class OnboardingUIWeb {
|
|
|
2854
3051
|
else {
|
|
2855
3052
|
otpErrorElement.style.display = 'none';
|
|
2856
3053
|
}
|
|
3054
|
+
// Ensure social buttons remain hidden when showing error on OTP screen
|
|
3055
|
+
// Call immediately and also with delays to catch any re-renders
|
|
3056
|
+
this.hideLoginElements();
|
|
3057
|
+
setTimeout(() => {
|
|
3058
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
3059
|
+
this.hideLoginElements();
|
|
3060
|
+
}
|
|
3061
|
+
}, 0);
|
|
3062
|
+
setTimeout(() => {
|
|
3063
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
3064
|
+
this.hideLoginElements();
|
|
3065
|
+
}
|
|
3066
|
+
}, 50);
|
|
3067
|
+
setTimeout(() => {
|
|
3068
|
+
if (this.otpVerificationScreen && this.otpVerificationScreen.parentElement) {
|
|
3069
|
+
this.hideLoginElements();
|
|
3070
|
+
}
|
|
3071
|
+
}, 150);
|
|
2857
3072
|
return;
|
|
2858
3073
|
}
|
|
2859
3074
|
}
|
|
@@ -3009,16 +3224,23 @@ export class OnboardingUIWeb {
|
|
|
3009
3224
|
* Reset OTP screen and show initial login form
|
|
3010
3225
|
*/
|
|
3011
3226
|
resetToLoginForm() {
|
|
3227
|
+
// Clear resend cooldown timer
|
|
3228
|
+
if (this.resendCooldownTimer) {
|
|
3229
|
+
clearInterval(this.resendCooldownTimer);
|
|
3230
|
+
this.resendCooldownTimer = null;
|
|
3231
|
+
}
|
|
3232
|
+
this.resendCooldown = 0;
|
|
3012
3233
|
// Clear OTP verification screen
|
|
3013
3234
|
if (this.otpVerificationScreen) {
|
|
3014
3235
|
this.otpVerificationScreen.remove();
|
|
3015
3236
|
this.otpVerificationScreen = null;
|
|
3016
3237
|
}
|
|
3017
|
-
// Remove loading/error mode classes
|
|
3238
|
+
// Remove loading/error mode classes and OTP active class
|
|
3018
3239
|
const card = this.rootElement?.querySelector('.onboarding-card');
|
|
3019
3240
|
if (card) {
|
|
3020
3241
|
card.classList.remove('onboarding-mode-loading');
|
|
3021
3242
|
card.classList.remove('onboarding-mode-error');
|
|
3243
|
+
card.classList.remove('onboarding-otp-active');
|
|
3022
3244
|
}
|
|
3023
3245
|
// Hide loading modal if exists (for inline components)
|
|
3024
3246
|
this.hideLoadingModal();
|
|
@@ -3037,10 +3259,18 @@ export class OnboardingUIWeb {
|
|
|
3037
3259
|
this.otpSent = false;
|
|
3038
3260
|
this.loading = false;
|
|
3039
3261
|
// Clear timer
|
|
3262
|
+
// Clear resend cooldown timer
|
|
3263
|
+
if (this.resendCooldownTimer) {
|
|
3264
|
+
clearInterval(this.resendCooldownTimer);
|
|
3265
|
+
this.resendCooldownTimer = null;
|
|
3266
|
+
}
|
|
3040
3267
|
this.resendCooldown = 0;
|
|
3041
3268
|
if (this.resendButton) {
|
|
3042
3269
|
this.resendButton.textContent = 'Resend';
|
|
3043
|
-
this.resendButton.
|
|
3270
|
+
this.resendButton.classList.remove('onboarding-otp-resend-link-disabled');
|
|
3271
|
+
this.resendButton.style.pointerEvents = 'auto';
|
|
3272
|
+
this.resendButton.style.cursor = 'pointer';
|
|
3273
|
+
this.resendButton.style.opacity = '1';
|
|
3044
3274
|
}
|
|
3045
3275
|
// Get auth methods
|
|
3046
3276
|
const authMethods = this.config.authMethods || ['otp', 'google'];
|