@seaverse/auth-sdk 0.3.7 → 0.3.9
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 +224 -11
- package/dist/auth-modal.css +1 -1
- package/dist/index.cjs +148 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +73 -2
- package/dist/index.js +148 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -791,6 +791,32 @@ interface BindInviteCodeResponse {
|
|
|
791
791
|
message: string;
|
|
792
792
|
};
|
|
793
793
|
}
|
|
794
|
+
/**
|
|
795
|
+
* Iframe token request message sent from child to parent
|
|
796
|
+
*/
|
|
797
|
+
interface IframeTokenRequestMessage {
|
|
798
|
+
type: 'seaverse:get_token';
|
|
799
|
+
requestId: string;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Iframe token response message sent from parent to child
|
|
803
|
+
*/
|
|
804
|
+
interface IframeTokenResponseMessage {
|
|
805
|
+
type: 'seaverse:token';
|
|
806
|
+
requestId: string;
|
|
807
|
+
payload: {
|
|
808
|
+
accessToken: string;
|
|
809
|
+
expiresIn: number;
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Iframe token error message sent from parent to child
|
|
814
|
+
*/
|
|
815
|
+
interface IframeTokenErrorMessage {
|
|
816
|
+
type: 'seaverse:token_error';
|
|
817
|
+
requestId: string;
|
|
818
|
+
error: string;
|
|
819
|
+
}
|
|
794
820
|
|
|
795
821
|
type models_AccountExistsErrorDetails = AccountExistsErrorDetails;
|
|
796
822
|
type models_ApiError = ApiError;
|
|
@@ -815,6 +841,9 @@ type models_ForkProjectResponse = ForkProjectResponse;
|
|
|
815
841
|
type models_HealthResponse = HealthResponse;
|
|
816
842
|
type models_HubProject = HubProject;
|
|
817
843
|
type models_HubProjectsListResponse = HubProjectsListResponse;
|
|
844
|
+
type models_IframeTokenErrorMessage = IframeTokenErrorMessage;
|
|
845
|
+
type models_IframeTokenRequestMessage = IframeTokenRequestMessage;
|
|
846
|
+
type models_IframeTokenResponseMessage = IframeTokenResponseMessage;
|
|
818
847
|
type models_InviteApplication = InviteApplication;
|
|
819
848
|
type models_InviteApplicationListResponse = InviteApplicationListResponse;
|
|
820
849
|
type models_InviteCode = InviteCode;
|
|
@@ -855,7 +884,7 @@ type models_UserInstalledSkillsListResponse = UserInstalledSkillsListResponse;
|
|
|
855
884
|
type models_VideoDetails = VideoDetails;
|
|
856
885
|
declare namespace models {
|
|
857
886
|
export { models_ErrorCode as ErrorCode };
|
|
858
|
-
export type { models_AccountExistsErrorDetails as AccountExistsErrorDetails, models_ApiError as ApiError, models_ApiServiceTokenResponse as ApiServiceTokenResponse, models_ApplyInviteResponse as ApplyInviteResponse, models_BindInviteCodeRequest as BindInviteCodeRequest, models_BindInviteCodeResponse as BindInviteCodeResponse, models_Container as Container, models_ContainerDetailResponse as ContainerDetailResponse, models_ContainerListResponse as ContainerListResponse, models_ContainerStatsResponse as ContainerStatsResponse, models_ConversationStatus as ConversationStatus, models_CreateMarketplaceSkillRequest as CreateMarketplaceSkillRequest, models_CreateVideoShareRequest as CreateVideoShareRequest, models_CreateVideoShareResponse as CreateVideoShareResponse, models_EmailVerificationResponse as EmailVerificationResponse, models_ForgotPasswordRequest as ForgotPasswordRequest, models_ForkProjectRequest as ForkProjectRequest, models_ForkProjectResponse as ForkProjectResponse, models_HealthResponse as HealthResponse, models_HubProject as HubProject, models_HubProjectsListResponse as HubProjectsListResponse, models_InviteApplication as InviteApplication, models_InviteApplicationListResponse as InviteApplicationListResponse, models_InviteCode as InviteCode, models_InviteCodeBindRequest as InviteCodeBindRequest, models_InviteCodeDetailResponse as InviteCodeDetailResponse, models_InviteCodeGenerateResponse as InviteCodeGenerateResponse, models_InviteCodeRequiredErrorData as InviteCodeRequiredErrorData, models_InviteCodeVerifyResponse as InviteCodeVerifyResponse, models_InviteStats as InviteStats, models_InviteStatsResponse as InviteStatsResponse, models_InviteUsage as InviteUsage, models_ListInviteUsagesRequest as ListInviteUsagesRequest, models_ListInviteUsagesResponse as ListInviteUsagesResponse, models_ListInvitesRequest as ListInvitesRequest, models_ListInvitesResponse as ListInvitesResponse, models_LoginRequest as LoginRequest, models_LoginResponse as LoginResponse, models_MarketplaceSkill as MarketplaceSkill, models_MarketplaceSkillsListResponse as MarketplaceSkillsListResponse, models_OAuthAuthorizeRequest as OAuthAuthorizeRequest, models_OAuthAuthorizeResponse as OAuthAuthorizeResponse, models_PublishProjectRequest as PublishProjectRequest, models_PublishSkillRequest as PublishSkillRequest, models_RegisterContainerRequest as RegisterContainerRequest, models_RegisterContainerResponse as RegisterContainerResponse, models_RegisterRequest as RegisterRequest, models_RegisterResponse as RegisterResponse, models_ResetPasswordRequest as ResetPasswordRequest, models_SocialMediaLink as SocialMediaLink, models_SocialMediaLinksResponse as SocialMediaLinksResponse, models_SpeechTokenResponse as SpeechTokenResponse, models_SubmitInviteApplicationRequest as SubmitInviteApplicationRequest, models_SuccessResponse as SuccessResponse, models_TrackAppTypeRequest as TrackAppTypeRequest, models_User as User, models_UserInstalledSkill as UserInstalledSkill, models_UserInstalledSkillsListResponse as UserInstalledSkillsListResponse, models_VideoDetails as VideoDetails };
|
|
887
|
+
export type { models_AccountExistsErrorDetails as AccountExistsErrorDetails, models_ApiError as ApiError, models_ApiServiceTokenResponse as ApiServiceTokenResponse, models_ApplyInviteResponse as ApplyInviteResponse, models_BindInviteCodeRequest as BindInviteCodeRequest, models_BindInviteCodeResponse as BindInviteCodeResponse, models_Container as Container, models_ContainerDetailResponse as ContainerDetailResponse, models_ContainerListResponse as ContainerListResponse, models_ContainerStatsResponse as ContainerStatsResponse, models_ConversationStatus as ConversationStatus, models_CreateMarketplaceSkillRequest as CreateMarketplaceSkillRequest, models_CreateVideoShareRequest as CreateVideoShareRequest, models_CreateVideoShareResponse as CreateVideoShareResponse, models_EmailVerificationResponse as EmailVerificationResponse, models_ForgotPasswordRequest as ForgotPasswordRequest, models_ForkProjectRequest as ForkProjectRequest, models_ForkProjectResponse as ForkProjectResponse, models_HealthResponse as HealthResponse, models_HubProject as HubProject, models_HubProjectsListResponse as HubProjectsListResponse, models_IframeTokenErrorMessage as IframeTokenErrorMessage, models_IframeTokenRequestMessage as IframeTokenRequestMessage, models_IframeTokenResponseMessage as IframeTokenResponseMessage, models_InviteApplication as InviteApplication, models_InviteApplicationListResponse as InviteApplicationListResponse, models_InviteCode as InviteCode, models_InviteCodeBindRequest as InviteCodeBindRequest, models_InviteCodeDetailResponse as InviteCodeDetailResponse, models_InviteCodeGenerateResponse as InviteCodeGenerateResponse, models_InviteCodeRequiredErrorData as InviteCodeRequiredErrorData, models_InviteCodeVerifyResponse as InviteCodeVerifyResponse, models_InviteStats as InviteStats, models_InviteStatsResponse as InviteStatsResponse, models_InviteUsage as InviteUsage, models_ListInviteUsagesRequest as ListInviteUsagesRequest, models_ListInviteUsagesResponse as ListInviteUsagesResponse, models_ListInvitesRequest as ListInvitesRequest, models_ListInvitesResponse as ListInvitesResponse, models_LoginRequest as LoginRequest, models_LoginResponse as LoginResponse, models_MarketplaceSkill as MarketplaceSkill, models_MarketplaceSkillsListResponse as MarketplaceSkillsListResponse, models_OAuthAuthorizeRequest as OAuthAuthorizeRequest, models_OAuthAuthorizeResponse as OAuthAuthorizeResponse, models_PublishProjectRequest as PublishProjectRequest, models_PublishSkillRequest as PublishSkillRequest, models_RegisterContainerRequest as RegisterContainerRequest, models_RegisterContainerResponse as RegisterContainerResponse, models_RegisterRequest as RegisterRequest, models_RegisterResponse as RegisterResponse, models_ResetPasswordRequest as ResetPasswordRequest, models_SocialMediaLink as SocialMediaLink, models_SocialMediaLinksResponse as SocialMediaLinksResponse, models_SpeechTokenResponse as SpeechTokenResponse, models_SubmitInviteApplicationRequest as SubmitInviteApplicationRequest, models_SuccessResponse as SuccessResponse, models_TrackAppTypeRequest as TrackAppTypeRequest, models_User as User, models_UserInstalledSkill as UserInstalledSkill, models_UserInstalledSkillsListResponse as UserInstalledSkillsListResponse, models_VideoDetails as VideoDetails };
|
|
859
888
|
}
|
|
860
889
|
|
|
861
890
|
/**
|
|
@@ -1027,6 +1056,48 @@ declare class SeaVerseBackendAPIClient {
|
|
|
1027
1056
|
* }
|
|
1028
1057
|
*/
|
|
1029
1058
|
setToken(token: string): void;
|
|
1059
|
+
/**
|
|
1060
|
+
* Get token from parent window via iframe communication
|
|
1061
|
+
* This method is designed for scenarios where the application is embedded in an iframe
|
|
1062
|
+
* and needs to obtain authentication tokens from the parent page
|
|
1063
|
+
*
|
|
1064
|
+
* @param options - Configuration options
|
|
1065
|
+
* @param options.timeout - Timeout in milliseconds (default: 30000)
|
|
1066
|
+
* @returns Promise that resolves with the access token
|
|
1067
|
+
*
|
|
1068
|
+
* @example
|
|
1069
|
+
* // In an iframe application
|
|
1070
|
+
* try {
|
|
1071
|
+
* const token = await client.getIframeToken({ timeout: 10000 });
|
|
1072
|
+
* client.setToken(token);
|
|
1073
|
+
* localStorage.setItem('token', token);
|
|
1074
|
+
* console.log('Successfully obtained token from parent');
|
|
1075
|
+
* } catch (error) {
|
|
1076
|
+
* console.error('Failed to get token from parent:', error);
|
|
1077
|
+
* }
|
|
1078
|
+
*
|
|
1079
|
+
* @example
|
|
1080
|
+
* // Parent page should listen for token requests and respond:
|
|
1081
|
+
* window.addEventListener('message', (event) => {
|
|
1082
|
+
* if (event.data.type === 'seaverse:get_token') {
|
|
1083
|
+
* const requestId = event.data.requestId;
|
|
1084
|
+
* // Get your token (from localStorage, API, etc.)
|
|
1085
|
+
* const token = localStorage.getItem('token');
|
|
1086
|
+
* // Send token back to iframe
|
|
1087
|
+
* event.source.postMessage({
|
|
1088
|
+
* type: 'seaverse:token',
|
|
1089
|
+
* requestId: requestId,
|
|
1090
|
+
* payload: {
|
|
1091
|
+
* accessToken: token,
|
|
1092
|
+
* expiresIn: 3600,
|
|
1093
|
+
* },
|
|
1094
|
+
* }, '*');
|
|
1095
|
+
* }
|
|
1096
|
+
* });
|
|
1097
|
+
*/
|
|
1098
|
+
getIframeToken(options?: {
|
|
1099
|
+
timeout?: number;
|
|
1100
|
+
}): Promise<string>;
|
|
1030
1101
|
/**
|
|
1031
1102
|
* Health check
|
|
1032
1103
|
* Check if the service is healthy
|
|
@@ -1523,4 +1594,4 @@ declare class Toast {
|
|
|
1523
1594
|
}
|
|
1524
1595
|
|
|
1525
1596
|
export { AuthFactory, AuthModal, AuthProvider, BuiltInHooks, ENVIRONMENT_CONFIGS, ErrorCode, SeaVerseBackendAPIClient, Toast, createAuthModal, detectEnvironment, getEnvironmentConfig, models };
|
|
1526
|
-
export type { AccountExistsErrorDetails, ApiError, ApiServiceTokenResponse, ApplyInviteResponse, AuthModalOptions, AuthModalResult, BindInviteCodeRequest, BindInviteCodeResponse, Container, ContainerDetailResponse, ContainerListResponse, ContainerStatsResponse, ConversationStatus, CreateMarketplaceSkillRequest, CreateVideoShareRequest, CreateVideoShareResponse, EmailVerificationResponse, Environment, EnvironmentConfig, ForgotPasswordRequest, ForkProjectRequest, ForkProjectResponse, HealthResponse, HubProject, HubProjectsListResponse, InviteApplication, InviteApplicationListResponse, InviteCode, InviteCodeBindRequest, InviteCodeDetailResponse, InviteCodeGenerateResponse, InviteCodeRequiredErrorData, InviteCodeVerifyResponse, InviteStats, InviteStatsResponse, InviteUsage, ListInviteUsagesRequest, ListInviteUsagesResponse, ListInvitesRequest, ListInvitesResponse, LoginRequest, LoginResponse, MarketplaceSkill, MarketplaceSkillsListResponse, OAuthAuthorizeRequest, OAuthAuthorizeResponse, PublishProjectRequest, PublishSkillRequest, RegisterContainerRequest, RegisterContainerResponse, RegisterRequest, RegisterResponse, ResetPasswordRequest, RetryOptions, SeaVerseBackendAPIClientOptions, SocialMediaLink, SocialMediaLinksResponse, SpeechTokenResponse, SubmitInviteApplicationRequest, SuccessResponse, ToastOptions, ToastType, TrackAppTypeRequest, User, UserInstalledSkill, UserInstalledSkillsListResponse, VideoDetails };
|
|
1597
|
+
export type { AccountExistsErrorDetails, ApiError, ApiServiceTokenResponse, ApplyInviteResponse, AuthModalOptions, AuthModalResult, BindInviteCodeRequest, BindInviteCodeResponse, Container, ContainerDetailResponse, ContainerListResponse, ContainerStatsResponse, ConversationStatus, CreateMarketplaceSkillRequest, CreateVideoShareRequest, CreateVideoShareResponse, EmailVerificationResponse, Environment, EnvironmentConfig, ForgotPasswordRequest, ForkProjectRequest, ForkProjectResponse, HealthResponse, HubProject, HubProjectsListResponse, IframeTokenErrorMessage, IframeTokenRequestMessage, IframeTokenResponseMessage, InviteApplication, InviteApplicationListResponse, InviteCode, InviteCodeBindRequest, InviteCodeDetailResponse, InviteCodeGenerateResponse, InviteCodeRequiredErrorData, InviteCodeVerifyResponse, InviteStats, InviteStatsResponse, InviteUsage, ListInviteUsagesRequest, ListInviteUsagesResponse, ListInvitesRequest, ListInvitesResponse, LoginRequest, LoginResponse, MarketplaceSkill, MarketplaceSkillsListResponse, OAuthAuthorizeRequest, OAuthAuthorizeResponse, PublishProjectRequest, PublishSkillRequest, RegisterContainerRequest, RegisterContainerResponse, RegisterRequest, RegisterResponse, ResetPasswordRequest, RetryOptions, SeaVerseBackendAPIClientOptions, SocialMediaLink, SocialMediaLinksResponse, SpeechTokenResponse, SubmitInviteApplicationRequest, SuccessResponse, ToastOptions, ToastType, TrackAppTypeRequest, User, UserInstalledSkill, UserInstalledSkillsListResponse, VideoDetails };
|
package/dist/index.js
CHANGED
|
@@ -1262,6 +1262,103 @@ class SeaVerseBackendAPIClient {
|
|
|
1262
1262
|
// Update the httpClient's auth
|
|
1263
1263
|
this.httpClient.auth = auth;
|
|
1264
1264
|
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Get token from parent window via iframe communication
|
|
1267
|
+
* This method is designed for scenarios where the application is embedded in an iframe
|
|
1268
|
+
* and needs to obtain authentication tokens from the parent page
|
|
1269
|
+
*
|
|
1270
|
+
* @param options - Configuration options
|
|
1271
|
+
* @param options.timeout - Timeout in milliseconds (default: 30000)
|
|
1272
|
+
* @returns Promise that resolves with the access token
|
|
1273
|
+
*
|
|
1274
|
+
* @example
|
|
1275
|
+
* // In an iframe application
|
|
1276
|
+
* try {
|
|
1277
|
+
* const token = await client.getIframeToken({ timeout: 10000 });
|
|
1278
|
+
* client.setToken(token);
|
|
1279
|
+
* localStorage.setItem('token', token);
|
|
1280
|
+
* console.log('Successfully obtained token from parent');
|
|
1281
|
+
* } catch (error) {
|
|
1282
|
+
* console.error('Failed to get token from parent:', error);
|
|
1283
|
+
* }
|
|
1284
|
+
*
|
|
1285
|
+
* @example
|
|
1286
|
+
* // Parent page should listen for token requests and respond:
|
|
1287
|
+
* window.addEventListener('message', (event) => {
|
|
1288
|
+
* if (event.data.type === 'seaverse:get_token') {
|
|
1289
|
+
* const requestId = event.data.requestId;
|
|
1290
|
+
* // Get your token (from localStorage, API, etc.)
|
|
1291
|
+
* const token = localStorage.getItem('token');
|
|
1292
|
+
* // Send token back to iframe
|
|
1293
|
+
* event.source.postMessage({
|
|
1294
|
+
* type: 'seaverse:token',
|
|
1295
|
+
* requestId: requestId,
|
|
1296
|
+
* payload: {
|
|
1297
|
+
* accessToken: token,
|
|
1298
|
+
* expiresIn: 3600,
|
|
1299
|
+
* },
|
|
1300
|
+
* }, '*');
|
|
1301
|
+
* }
|
|
1302
|
+
* });
|
|
1303
|
+
*/
|
|
1304
|
+
getIframeToken(options) {
|
|
1305
|
+
// Only works in browser environment
|
|
1306
|
+
if (typeof window === 'undefined') {
|
|
1307
|
+
return Promise.reject(new Error('getIframeToken() can only be used in browser environment'));
|
|
1308
|
+
}
|
|
1309
|
+
// Check if we're in an iframe
|
|
1310
|
+
if (window.self === window.top) {
|
|
1311
|
+
return Promise.reject(new Error('getIframeToken() can only be used inside an iframe'));
|
|
1312
|
+
}
|
|
1313
|
+
const timeout = options?.timeout || 30000; // Default 30 seconds
|
|
1314
|
+
const requestId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1315
|
+
return new Promise((resolve, reject) => {
|
|
1316
|
+
let timeoutId = null;
|
|
1317
|
+
let messageHandler = null;
|
|
1318
|
+
// Cleanup function
|
|
1319
|
+
const cleanup = () => {
|
|
1320
|
+
if (timeoutId) {
|
|
1321
|
+
clearTimeout(timeoutId);
|
|
1322
|
+
timeoutId = null;
|
|
1323
|
+
}
|
|
1324
|
+
if (messageHandler) {
|
|
1325
|
+
window.removeEventListener('message', messageHandler);
|
|
1326
|
+
messageHandler = null;
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
// Set up timeout
|
|
1330
|
+
timeoutId = setTimeout(() => {
|
|
1331
|
+
cleanup();
|
|
1332
|
+
reject(new Error(`Token request timeout after ${timeout}ms`));
|
|
1333
|
+
}, timeout);
|
|
1334
|
+
// Set up message listener
|
|
1335
|
+
messageHandler = (event) => {
|
|
1336
|
+
const data = event.data;
|
|
1337
|
+
// Check if this is a response to our request
|
|
1338
|
+
if (data &&
|
|
1339
|
+
typeof data === 'object' &&
|
|
1340
|
+
data.requestId === requestId) {
|
|
1341
|
+
if (data.type === 'seaverse:token') {
|
|
1342
|
+
cleanup();
|
|
1343
|
+
const tokenData = data;
|
|
1344
|
+
resolve(tokenData.payload.accessToken);
|
|
1345
|
+
}
|
|
1346
|
+
else if (data.type === 'seaverse:token_error') {
|
|
1347
|
+
cleanup();
|
|
1348
|
+
const errorData = data;
|
|
1349
|
+
reject(new Error(errorData.error || 'Failed to get token from parent'));
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
window.addEventListener('message', messageHandler);
|
|
1354
|
+
// Send request to parent
|
|
1355
|
+
const requestMessage = {
|
|
1356
|
+
type: 'seaverse:get_token',
|
|
1357
|
+
requestId,
|
|
1358
|
+
};
|
|
1359
|
+
window.parent.postMessage(requestMessage, '*');
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
1265
1362
|
// ============================================================================
|
|
1266
1363
|
// Authentication & OAuth APIs
|
|
1267
1364
|
// ============================================================================
|
|
@@ -3068,21 +3165,37 @@ class AuthModal {
|
|
|
3068
3165
|
const container = document.createElement('div');
|
|
3069
3166
|
container.id = 'inviteCodeForm';
|
|
3070
3167
|
container.className = 'auth-form-view hidden';
|
|
3071
|
-
// Icon
|
|
3168
|
+
// Icon - 使用星星图标
|
|
3072
3169
|
const icon = document.createElement('div');
|
|
3073
|
-
icon.className = '
|
|
3074
|
-
|
|
3170
|
+
icon.className = 'invite-code-icon';
|
|
3171
|
+
const iconGlow = document.createElement('div');
|
|
3172
|
+
iconGlow.className = 'icon-glow';
|
|
3173
|
+
icon.appendChild(iconGlow);
|
|
3174
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
3175
|
+
svg.setAttribute('class', 'icon-star');
|
|
3176
|
+
svg.setAttribute('width', '56');
|
|
3177
|
+
svg.setAttribute('height', '56');
|
|
3178
|
+
svg.setAttribute('viewBox', '0 0 24 24');
|
|
3179
|
+
svg.setAttribute('fill', 'none');
|
|
3180
|
+
svg.setAttribute('stroke', 'currentColor');
|
|
3181
|
+
svg.setAttribute('stroke-width', '1.5');
|
|
3182
|
+
svg.setAttribute('stroke-linecap', 'round');
|
|
3183
|
+
svg.setAttribute('stroke-linejoin', 'round');
|
|
3184
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
3185
|
+
path.setAttribute('d', 'M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z');
|
|
3186
|
+
svg.appendChild(path);
|
|
3187
|
+
icon.appendChild(svg);
|
|
3075
3188
|
container.appendChild(icon);
|
|
3076
3189
|
// Header
|
|
3077
3190
|
const header = document.createElement('div');
|
|
3078
3191
|
header.className = 'auth-form-header';
|
|
3079
3192
|
const title = document.createElement('h2');
|
|
3080
3193
|
title.className = 'auth-form-title';
|
|
3081
|
-
title.textContent = '
|
|
3194
|
+
title.textContent = 'Bind Invitation Code';
|
|
3082
3195
|
const subtitle = document.createElement('p');
|
|
3083
3196
|
subtitle.className = 'auth-form-subtitle';
|
|
3084
3197
|
subtitle.id = 'inviteCodeSubtitle';
|
|
3085
|
-
subtitle.textContent = '
|
|
3198
|
+
subtitle.textContent = 'Complete your registration by entering an invitation code';
|
|
3086
3199
|
header.appendChild(title);
|
|
3087
3200
|
header.appendChild(subtitle);
|
|
3088
3201
|
container.appendChild(header);
|
|
@@ -3090,7 +3203,7 @@ class AuthModal {
|
|
|
3090
3203
|
const form = document.createElement('form');
|
|
3091
3204
|
form.id = 'inviteCodeFormElement';
|
|
3092
3205
|
form.className = 'auth-form';
|
|
3093
|
-
const codeGroup = this.createFormGroup('inviteCodeInput', 'Invitation
|
|
3206
|
+
const codeGroup = this.createFormGroup('inviteCodeInput', 'Invitation code *', 'text', 'Enter your invitation code');
|
|
3094
3207
|
form.appendChild(codeGroup);
|
|
3095
3208
|
const submitBtn = document.createElement('button');
|
|
3096
3209
|
submitBtn.type = 'submit';
|
|
@@ -3098,39 +3211,41 @@ class AuthModal {
|
|
|
3098
3211
|
submitBtn.className = 'btn-auth-primary';
|
|
3099
3212
|
const btnText = document.createElement('span');
|
|
3100
3213
|
btnText.className = 'btn-text';
|
|
3101
|
-
btnText.textContent = '
|
|
3214
|
+
btnText.textContent = 'Get Started';
|
|
3102
3215
|
const btnLoader = document.createElement('span');
|
|
3103
3216
|
btnLoader.className = 'btn-loader hidden';
|
|
3104
|
-
|
|
3217
|
+
const spinnerSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
3218
|
+
spinnerSvg.setAttribute('class', 'spinner');
|
|
3219
|
+
spinnerSvg.setAttribute('viewBox', '0 0 24 24');
|
|
3220
|
+
const track = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
3221
|
+
track.setAttribute('class', 'spinner-track');
|
|
3222
|
+
track.setAttribute('cx', '12');
|
|
3223
|
+
track.setAttribute('cy', '12');
|
|
3224
|
+
track.setAttribute('r', '10');
|
|
3225
|
+
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
3226
|
+
circle.setAttribute('class', 'spinner-circle');
|
|
3227
|
+
circle.setAttribute('cx', '12');
|
|
3228
|
+
circle.setAttribute('cy', '12');
|
|
3229
|
+
circle.setAttribute('r', '10');
|
|
3230
|
+
spinnerSvg.appendChild(track);
|
|
3231
|
+
spinnerSvg.appendChild(circle);
|
|
3232
|
+
btnLoader.appendChild(spinnerSvg);
|
|
3105
3233
|
submitBtn.appendChild(btnText);
|
|
3106
3234
|
submitBtn.appendChild(btnLoader);
|
|
3107
3235
|
form.appendChild(submitBtn);
|
|
3108
3236
|
container.appendChild(form);
|
|
3109
|
-
//
|
|
3110
|
-
const
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
const
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
applyInviteText.appendChild(applyInviteLink);
|
|
3122
|
-
applyInviteSection.appendChild(applyInviteText);
|
|
3123
|
-
container.appendChild(applyInviteSection);
|
|
3124
|
-
// Footer
|
|
3125
|
-
const footer = document.createElement('div');
|
|
3126
|
-
footer.className = 'auth-footer forgot-footer';
|
|
3127
|
-
const backLink = document.createElement('a');
|
|
3128
|
-
backLink.href = '#';
|
|
3129
|
-
backLink.id = 'backToLoginFromInvite';
|
|
3130
|
-
backLink.className = 'back-to-login';
|
|
3131
|
-
backLink.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5M12 19l-7-7 7-7"/></svg><span>Back to Sign In</span>';
|
|
3132
|
-
footer.appendChild(backLink);
|
|
3133
|
-
container.appendChild(footer);
|
|
3237
|
+
// 分隔线
|
|
3238
|
+
const divider = document.createElement('div');
|
|
3239
|
+
divider.className = 'invite-code-divider';
|
|
3240
|
+
divider.textContent = "DON'T HAVE CODE?";
|
|
3241
|
+
container.appendChild(divider);
|
|
3242
|
+
// Apply invite 按钮
|
|
3243
|
+
const applyInviteBtn = document.createElement('button');
|
|
3244
|
+
applyInviteBtn.type = 'button';
|
|
3245
|
+
applyInviteBtn.id = 'showApplyInviteForm';
|
|
3246
|
+
applyInviteBtn.className = 'btn-apply-invite';
|
|
3247
|
+
applyInviteBtn.textContent = 'Apply for access';
|
|
3248
|
+
container.appendChild(applyInviteBtn);
|
|
3134
3249
|
return container;
|
|
3135
3250
|
}
|
|
3136
3251
|
createApplyInviteForm() {
|