@seaverse/auth-sdk 0.3.5 → 0.3.7
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 +42 -15
- package/dist/auth-modal.css +1 -1
- package/dist/index.cjs +246 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +46 -5
- package/dist/index.js +246 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -268,6 +268,12 @@ const authModal = new AuthModal({
|
|
|
268
268
|
// AuthModal 会自动显示邀请码输入界面
|
|
269
269
|
},
|
|
270
270
|
|
|
271
|
+
// 申请邀请码成功回调(可选)
|
|
272
|
+
onApplyInviteSuccess: (applicationId, email) => {
|
|
273
|
+
console.log('邀请码申请已提交:', applicationId, email);
|
|
274
|
+
// 可以在这里添加自定义逻辑,如显示提示信息
|
|
275
|
+
},
|
|
276
|
+
|
|
271
277
|
// 错误回调
|
|
272
278
|
onError: (error) => {
|
|
273
279
|
console.error('认证错误:', error.message);
|
|
@@ -353,7 +359,6 @@ const authModal = new AuthModal({
|
|
|
353
359
|
|
|
354
360
|
**配置字段说明**:
|
|
355
361
|
- `returnUrl`:**可选** - OAuth 登录后返回的 URL,不填则默认为 `window.location.href`
|
|
356
|
-
- `oauthDesktopURL`:**可选** - 桌面应用 OAuth 回调 URL,如果提供则优先使用此 URL(优先级:`oauthDesktopURL` > `returnUrl` > `window.location.href`)
|
|
357
362
|
- `enableOAuth.google`:是否启用 Google 登录
|
|
358
363
|
- `enableOAuth.discord`:是否启用 Discord 登录
|
|
359
364
|
- `enableOAuth.github`:是否启用 GitHub 登录
|
|
@@ -387,19 +392,6 @@ const authModal3 = new AuthModal({
|
|
|
387
392
|
github: true,
|
|
388
393
|
},
|
|
389
394
|
});
|
|
390
|
-
|
|
391
|
-
// 示例4:桌面应用 OAuth 回调(优先级最高)
|
|
392
|
-
const authModal4 = new AuthModal({
|
|
393
|
-
client,
|
|
394
|
-
theme: 'dark',
|
|
395
|
-
oauthDesktopURL: 'myapp://oauth/callback', // 桌面应用自定义协议 URL
|
|
396
|
-
enableOAuth: {
|
|
397
|
-
google: true,
|
|
398
|
-
discord: true,
|
|
399
|
-
github: true,
|
|
400
|
-
},
|
|
401
|
-
});
|
|
402
|
-
// 登录成功后会跳转到 myapp://oauth/callback?token=xxx
|
|
403
395
|
```
|
|
404
396
|
|
|
405
397
|
#### 处理 OAuth 回调
|
|
@@ -514,6 +506,25 @@ await client.uninstallSkill({
|
|
|
514
506
|
### 7. 邀请码管理
|
|
515
507
|
|
|
516
508
|
```typescript
|
|
509
|
+
// 申请邀请码(当用户没有邀请码时)
|
|
510
|
+
const application = await client.applyInvite({
|
|
511
|
+
email: 'player@example.com',
|
|
512
|
+
reason: 'I want to join this amazing platform to build innovative applications and connect with the community.'
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
if (application.success) {
|
|
516
|
+
console.log('申请已提交:', application.data);
|
|
517
|
+
console.log('申请ID:', application.data.id);
|
|
518
|
+
console.log('状态:', application.data.status); // 'pending'
|
|
519
|
+
} else {
|
|
520
|
+
// 处理错误
|
|
521
|
+
if (application.code === 'APPLICATION_DUPLICATE') {
|
|
522
|
+
console.log('您在过去24小时内已提交过申请');
|
|
523
|
+
} else {
|
|
524
|
+
console.error('申请失败:', application.error);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
517
528
|
// 列出我的邀请码
|
|
518
529
|
const invites = await client.listInvites({
|
|
519
530
|
status: 'active',
|
|
@@ -612,6 +623,14 @@ if (verifyToken) {
|
|
|
612
623
|
|
|
613
624
|
当使用外部邮箱注册或 OAuth 登录但未提供邀请码时,会创建临时账户并需要后续绑定邀请码激活。
|
|
614
625
|
|
|
626
|
+
**申请邀请码功能**:
|
|
627
|
+
|
|
628
|
+
如果用户没有邀请码,AuthModal 提供了内置的申请功能:
|
|
629
|
+
1. 在邀请码输入界面,用户可以点击 "Don't have an invitation code? Apply for one" 链接
|
|
630
|
+
2. 自动跳转到申请邀请码表单
|
|
631
|
+
3. 用户填写邮箱和申请原因(10-500字符)
|
|
632
|
+
4. 提交后会调用 `applyInvite()` API,后台审核通过后会通过邮件发送邀请码
|
|
633
|
+
|
|
615
634
|
**自动跳转机制**:
|
|
616
635
|
- 当 `login()` 返回 `INVITE_CODE_REQUIRED` 错误且包含 `redirectUrl` 时,SDK 会自动将页面重定向到该 URL
|
|
617
636
|
- redirectUrl 通常包含 `error_code=INVITE_CODE_REQUIRED&user_id=xxx&email=xxx` 参数
|
|
@@ -996,6 +1015,7 @@ const response = await client.register({ email, password });
|
|
|
996
1015
|
|
|
997
1016
|
| 方法 | 参数 | 返回值 | 说明 |
|
|
998
1017
|
|------|------|--------|------|
|
|
1018
|
+
| `applyInvite()` | `{ email, reason }` | `ApplyInviteResponse` | 申请邀请码(reason 需10-500字符)|
|
|
999
1019
|
| `listInvites()` | `{ page?, page_size?, status? }` | `ListInvitesResponse` | 列出我的邀请码 |
|
|
1000
1020
|
| `getInviteStats()` | - | `InviteStatsResponse` | 获取邀请码统计 |
|
|
1001
1021
|
| `getInvite()` | `inviteId: string` | `InviteCodeDetailResponse` | 获取邀请码详情 |
|
|
@@ -1346,6 +1366,7 @@ interface AuthModalOptions {
|
|
|
1346
1366
|
onLoginSuccess?: (token: string, user: any) => void;
|
|
1347
1367
|
onSignupSuccess?: (token: string, user: any) => void;
|
|
1348
1368
|
onInviteCodeRequired?: (userId: string, email: string) => void; // 当需要邀请码激活时的回调
|
|
1369
|
+
onApplyInviteSuccess?: (applicationId: string, email: string) => void; // 申请邀请码成功的回调
|
|
1349
1370
|
onError?: (error: Error) => void;
|
|
1350
1371
|
returnUrl?: string; // OAuth 登录后返回的 URL,可选,默认为 window.location.href
|
|
1351
1372
|
enableOAuth?: {
|
|
@@ -1523,7 +1544,13 @@ MIT © [SeaVerse Team](mailto:support@seaverse.com)
|
|
|
1523
1544
|
|
|
1524
1545
|
## 更新日志
|
|
1525
1546
|
|
|
1526
|
-
### v0.
|
|
1547
|
+
### v0.3.6 (当前版本)
|
|
1548
|
+
- 🧹 **代码清理**: 移除桌面应用OAuth回调相关功能
|
|
1549
|
+
- 移除 `oauthDesktopURL` 配置选项
|
|
1550
|
+
- 简化OAuth流程,统一使用 `returnUrl` 参数
|
|
1551
|
+
- 清理相关文档和代码注释
|
|
1552
|
+
|
|
1553
|
+
### v0.2.5
|
|
1527
1554
|
- 🔄 **响应格式兼容**: 自动兼容包装格式和扁平格式的API响应
|
|
1528
1555
|
- 修复登录时提示 "Invalid response from server" 的问题
|
|
1529
1556
|
- `login()`, `register()`, `getCurrentUser()` 方法自动解包 `data` 字段
|
package/dist/auth-modal.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--font-display:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--color-neon-green:#10b981;--color-text-primary:#fff;--color-text-secondary:#a1a1aa;--color-text-tertiary:#71717a;--gradient-neon:linear-gradient(135deg,#10b981,#06b6d4)}.auth-modal{align-items:center;animation:modalFadeIn .3s ease-out;display:flex;inset:0;justify-content:center;overflow:hidden;padding:20px;position:fixed;z-index:9999}.auth-modal.hidden{display:none}@keyframes modalFadeIn{0%{opacity:0}to{opacity:1}}.auth-modal-backdrop{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:rgba(0,0,0,.85);inset:0;position:absolute}.auth-modal-content{animation:modalSlideUp .4s cubic-bezier(.4,0,.2,1);background:#0d0d0d;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 25px 80px rgba(0,0,0,.8);display:grid;grid-template-columns:1fr 1fr;max-height:90vh;max-width:900px;overflow:hidden;position:relative;transition:max-width .3s ease;width:100%;z-index:10}.auth-modal-content:has(#loginForm:not(.hidden)){grid-template-columns:1fr auto;max-width:none;width:auto}.auth-modal-content:has(#loginForm:not(.hidden)) .auth-modal-right{min-width:0;width:auto}.auth-modal-content:has(#authMessage:not(.hidden)){grid-template-columns:1fr;max-width:480px}.auth-modal-content:has(#authMessage:not(.hidden)) .auth-modal-left{display:none}@keyframes modalSlideUp{0%{opacity:0;transform:translateY(30px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.auth-modal-left{background:#000;border-right:1px solid hsla(0,0%,100%,.05);display:flex;flex-direction:column;overflow:hidden;padding:32px;position:relative}.auth-modal-left:before{animation:meshRotate 20s linear infinite;background:radial-gradient(at 0 0,rgba(99,102,241,.3) 0,transparent 50%),radial-gradient(at 50% 0,rgba(139,92,246,.3) 0,transparent 50%),radial-gradient(at 100% 0,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 0 50%,rgba(16,185,129,.3) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(244,63,94,.3) 0,transparent 50%),radial-gradient(at 0 100%,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(139,92,246,.3) 0,transparent 50%);content:"";filter:blur(80px);height:200%;inset:-50%;opacity:.6;position:absolute;width:200%}@keyframes meshRotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.65' numOctaves='3' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.05'/%3E%3C/svg%3E");content:"";inset:0;mix-blend-mode:overlay;opacity:.4;pointer-events:none;position:absolute}.auth-modal-logo{align-items:center;display:flex;gap:10px;position:relative;z-index:10}.auth-modal-logo .logo-icon{filter:drop-shadow(0 0 10px rgba(16,185,129,.3));height:28px;width:28px}.auth-modal-logo .logo-text{color:#fff;font-family:var(--font-display);font-size:18px;font-weight:700;text-shadow:0 0 20px rgba(0,0,0,.5)}.auth-modal-decoration{inset:0;overflow:hidden;pointer-events:none;position:absolute}.auth-modal-decoration .glow-orb-1{animation:breathe 8s ease-in-out infinite;background:radial-gradient(circle,hsla(0,0%,100%,.05) 0,transparent 70%);border-radius:50%;filter:blur(60px);height:400px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:400px}@keyframes breathe{0%,to{opacity:.5;transform:translate(-50%,-50%) scale(1)}50%{opacity:.8;transform:translate(-50%,-50%) scale(1.2)}}.auth-modal-decoration .glow-orb-2{animation:breathe 10s ease-in-out infinite;animation-delay:2s;background:radial-gradient(circle,rgba(139,92,246,.08) 0,transparent 70%);border-radius:50%;filter:blur(50px);height:300px;pointer-events:none;position:absolute;right:-10%;top:20%;width:300px}.auth-modal-branding{margin-bottom:48px;margin-top:auto;position:relative;z-index:10}.auth-modal-branding .branding-title{color:#fff;font-family:var(--font-display);font-size:36px;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:12px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.auth-modal-branding .branding-subtitle{color:hsla(0,0%,100%,.8);font-size:14px;line-height:1.6;max-width:260px}.auth-modal-right{background:#121212;display:flex;flex-direction:column;max-height:90vh;overflow-y:auto;padding:56px 48px 42px;position:relative}.auth-modal-right::-webkit-scrollbar{width:6px}.auth-modal-right::-webkit-scrollbar-track{background:transparent}.auth-modal-right::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.1);border-radius:3px}.auth-modal-close{align-items:center;background:transparent;border:none;border-radius:8px;color:hsla(0,0%,100%,.5);cursor:pointer;display:flex;height:36px;justify-content:center;position:absolute;right:16px;top:16px;transition:all .2s ease;width:36px;z-index:20}.auth-modal-close:hover{background:hsla(0,0%,100%,.1);color:#fff}.auth-form-view{animation:formFadeIn .3s ease-out}#loginForm .form-input{width:360px}@keyframes formFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.auth-form-view.hidden{display:none}.auth-form-header{margin-bottom:28px;text-align:center}.auth-form-title{color:#fff;font-family:var(--font-display);font-size:26px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}.auth-form-subtitle{color:var(--color-text-secondary);font-size:14px}.auth-form{gap:16px}.auth-form,.form-group{display:flex;flex-direction:column}.form-group{gap:6px}.form-label{font-size:12px;font-weight:500;letter-spacing:.02em;opacity:.9;text-transform:uppercase}.form-input,.form-label{color:var(--color-text-primary)}.form-input{background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:8px;font-family:var(--font-sans);font-size:14px;height:40px;outline:none;padding:0 14px;transition:all .2s ease;width:100%}.form-input::placeholder{color:hsla(0,0%,100%,.35)}.form-input:hover{border-color:hsla(0,0%,100%,.15)}.form-input:focus{background:rgba(30,30,30,.9);border-color:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.15)}.form-input:invalid:not(:placeholder-shown){border-color:#ff006e}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon .form-input{padding-right:40px}.input-icon-btn{align-items:center;background:transparent;border:none;border-radius:4px;color:hsla(0,0%,100%,.4);cursor:pointer;display:flex;justify-content:center;padding:6px;position:absolute;right:8px;transition:color .2s ease}.input-icon-btn:hover{background:hsla(0,0%,100%,.05);color:hsla(0,0%,100%,.7)}.input-icon-btn .hidden{display:none}.strength-text{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:12px;font-weight:500;gap:6px;margin-top:4px}.form-group-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:8px}.form-group-header .form-label{margin-bottom:0}.forgot-password-link{color:hsla(0,0%,100%,.5);font-size:13px;font-weight:500;position:relative;text-decoration:none;transition:all .25s ease}.forgot-password-link:after{background:#10b981;bottom:-2px;content:"";height:1px;left:0;position:absolute;transition:width .3s ease;width:0}.forgot-password-link:hover{color:#10b981}.forgot-password-link:hover:after{width:100%}.link-primary{color:var(--color-neon-green);font-weight:600;position:relative;text-decoration:none;text-shadow:0 0 10px rgba(0,255,136,.3);transition:all .2s ease}.link-primary:after{background:var(--color-neon-green);bottom:-2px;content:"";height:1px;left:0;position:absolute;transform:scaleX(0);transform-origin:right;transition:transform .3s ease;width:100%}.link-primary:hover{color:#0f8;text-shadow:0 0 20px rgba(0,255,136,.5)}.link-primary:hover:after{transform:scaleX(1);transform-origin:left}.btn-auth-primary{align-items:center;background:var(--gradient-neon);border:none;border-radius:10px;box-shadow:0 4px 12px rgba(16,185,129,.25);color:#000;cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:600;gap:8px;height:44px;justify-content:center;margin-top:8px;overflow:hidden;padding:0 24px;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);width:100%}.btn-auth-primary:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.2) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-auth-primary:hover{box-shadow:0 8px 20px rgba(16,185,129,.35);transform:translateY(-2px)}.btn-auth-primary:hover:before{opacity:1}.btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.25);transform:translateY(0)}.btn-auth-primary:disabled{cursor:not-allowed;opacity:.6;transform:none}.btn-auth-primary .btn-text{position:relative;z-index:2}.btn-auth-primary .btn-loader{align-items:center;display:flex;justify-content:center;position:relative;z-index:2}.btn-auth-primary .btn-loader.hidden{display:none}.spinner{animation:spin .8s linear infinite;fill:none;height:20px;stroke-width:3;width:20px}@keyframes spin{to{transform:rotate(1turn)}}.spinner-track{stroke:rgba(0,0,0,.2)}.spinner-circle{animation:spinDash 1.2s ease-in-out infinite;stroke:#000;stroke-dasharray:50;stroke-dashoffset:50}@keyframes spinDash{0%{stroke-dashoffset:50}50%{stroke-dashoffset:12.5}to{stroke-dashoffset:50}}.forgot-password-icon{align-items:center;display:flex;height:100px;justify-content:center;margin:0 auto 24px;position:relative;width:100px}.forgot-password-icon .icon-glow{animation:pulseGlow 3s ease-in-out infinite;background:radial-gradient(circle,rgba(16,185,129,.25) 0,transparent 70%);border-radius:50%;filter:blur(15px);inset:-10px;position:absolute}@keyframes pulseGlow{0%,to{opacity:.5;transform:scale(.95)}50%{opacity:.8;transform:scale(1.05)}}.forgot-password-icon .icon-lock{animation:floatIcon 4s ease-in-out infinite;color:#10b981;filter:drop-shadow(0 0 10px rgba(16,185,129,.4));position:relative;z-index:2}@keyframes floatIcon{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.btn-forgot-password{align-items:center;display:flex;gap:8px;justify-content:center}.btn-forgot-password .btn-arrow{transition:transform .3s ease}.btn-forgot-password:hover .btn-arrow{transform:translateX(4px)}.auth-footer{margin-top:24px;text-align:center}.forgot-footer{display:flex;justify-content:center}.back-to-login{align-items:center;border-radius:6px;color:var(--color-text-secondary);display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:8px 12px;text-decoration:none;transition:all .2s ease}.back-to-login:hover{background:rgba(16,185,129,.05);color:var(--color-neon-green)}.back-to-login svg{transition:transform .3s ease}.back-to-login:hover svg{transform:translateX(-4px)}.auth-message-content{align-items:center;display:flex;flex-direction:column;padding:24px;text-align:center}.message-icon{align-items:center;background:rgba(16,185,129,.1);border-radius:50%;color:#10b981;display:flex;height:80px;justify-content:center;margin-bottom:24px;width:80px}.message-icon svg{animation:successPulse 2s ease-in-out infinite;filter:drop-shadow(0 0 10px rgba(16,185,129,.3))}@keyframes successPulse{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}.message-title{color:#fff;font-family:var(--font-display);font-size:24px;font-weight:700;margin-bottom:12px}.message-text{color:var(--color-text-secondary);font-size:14px;line-height:1.6;margin-bottom:24px}.divider{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:11px;font-weight:600;gap:12px;letter-spacing:.08em;margin:24px 0 20px;position:relative;text-align:center}.divider:after,.divider:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.1),transparent);content:"";flex:1;height:1px}.social-buttons-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr}.btn-social{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;margin:0;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1)}.btn-social:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social:hover:before{opacity:1}.btn-social:active{transform:translateY(0)}.btn-social svg{flex-shrink:0;height:20px;width:20px}.btn-social span{position:relative;white-space:nowrap;z-index:2}.btn-social-full{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1);width:100%}.btn-social-full:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social-full:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social-full:hover:before{opacity:1}.btn-social-full:active{transform:translateY(0)}.btn-social-full svg{flex-shrink:0;height:20px;width:20px}.btn-social-full span{position:relative;z-index:2}@media (max-width:768px){.auth-modal-content{border-radius:0;grid-template-columns:1fr;max-height:100vh;max-width:100%}.auth-modal-left{display:none}.auth-modal-right{max-height:100vh;padding:24px}.auth-form-title{font-size:22px}#loginForm .form-input{width:100%}.btn-auth-primary{font-size:15px;height:48px}.social-buttons-grid{gap:10px;grid-template-columns:1fr}.btn-social,.btn-social-full{height:48px}}@media (max-width:480px){.auth-modal{padding:0}.auth-modal-content{border-radius:0;max-height:100vh}.auth-modal-right{padding:20px 16px}.auth-form-header{margin-bottom:20px}}.auth-modal-light .auth-modal-backdrop{backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);background:hsla(0,0%,100%,.75)}.auth-modal-light .auth-modal-content{background:linear-gradient(135deg,#fdfbf7,#f8f6f2);border:1px solid rgba(16,185,129,.1);box-shadow:0 50px 100px rgba(0,0,0,.12),0 20px 40px rgba(0,0,0,.08),inset 0 0 0 1px hsla(0,0%,100%,.9)}.auth-modal-light .auth-modal-left{background:linear-gradient(135deg,#fff,#faf9f7);border-right:1px solid rgba(16,185,129,.08);box-shadow:2px 0 20px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .auth-modal-left:before{background:radial-gradient(at 0 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 50% 0,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 100% 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 0 50%,rgba(52,211,153,.05) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 0 100%,rgba(16,185,129,.07) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(52,211,153,.06) 0,transparent 50%);filter:blur(60px);opacity:.9}.auth-modal-light .auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.02'/%3E%3C/svg%3E");mix-blend-mode:multiply;opacity:.6}.auth-modal-light .auth-modal-logo .logo-icon{filter:drop-shadow(0 2px 8px rgba(16,185,129,.25))}.auth-modal-light .auth-modal-logo .logo-text{color:#0a0a0a;text-shadow:0 1px 2px rgba(16,185,129,.1)}.auth-modal-light .auth-modal-decoration .glow-orb-1{background:radial-gradient(circle,rgba(16,185,129,.08) 0,transparent 70%);filter:blur(80px)}.auth-modal-light .auth-modal-decoration .glow-orb-2{background:radial-gradient(circle,rgba(6,182,212,.06) 0,transparent 70%);filter:blur(70px)}.auth-modal-light .auth-modal-branding .branding-title{background:linear-gradient(135deg,#0a0a0a,#1a1a1a);-webkit-background-clip:text;color:#0a0a0a;text-shadow:0 2px 12px rgba(16,185,129,.12);-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-modal-branding .branding-subtitle{color:rgba(0,0,0,.6)}.auth-modal-light .auth-modal-right{backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);background:hsla(0,0%,100%,.85);box-shadow:-2px 0 20px rgba(0,0,0,.03)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb{background:rgba(16,185,129,.2)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb:hover{background:rgba(16,185,129,.3)}.auth-modal-light .auth-modal-close{color:rgba(0,0,0,.4)}.auth-modal-light .auth-modal-close:hover{background:rgba(16,185,129,.08);color:#0a0a0a}.auth-modal-light .auth-form-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-form-subtitle{color:rgba(0,0,0,.5)}.auth-modal-light .form-label{color:#0a0a0a;opacity:.7}.auth-modal-light .form-input{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 1px 2px rgba(0,0,0,.02),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#0a0a0a}.auth-modal-light .form-input::placeholder{color:rgba(0,0,0,.3)}.auth-modal-light .form-input:hover{border-color:rgba(16,185,129,.2);box-shadow:0 2px 4px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .form-input:focus{background:#fff;border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.12),0 2px 8px rgba(16,185,129,.08)}.auth-modal-light .form-input:invalid:not(:placeholder-shown){border-color:#ff006e;box-shadow:0 0 0 3px rgba(255,0,110,.1)}.auth-modal-light .input-icon-btn{color:rgba(0,0,0,.4)}.auth-modal-light .input-icon-btn:hover{color:rgba(0,0,0,.7)}.auth-modal-light .forgot-password-link{color:#10b981}.auth-modal-light .forgot-password-link:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .strength-text{color:rgba(0,0,0,.45)}.auth-modal-light .btn-auth-primary{background:linear-gradient(135deg,#10b981,#059669);border:none;box-shadow:0 4px 12px rgba(16,185,129,.25),0 2px 4px rgba(16,185,129,.15),inset 0 0 0 1px hsla(0,0%,100%,.3);color:#fff}.auth-modal-light .btn-auth-primary:hover{background:linear-gradient(135deg,#059669,#047857);box-shadow:0 6px 16px rgba(16,185,129,.3),0 3px 6px rgba(16,185,129,.2),inset 0 0 0 1px hsla(0,0%,100%,.4);transform:translateY(-1px)}.auth-modal-light .btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.2),0 1px 3px rgba(16,185,129,.15);transform:translateY(0)}.auth-modal-light .btn-auth-primary:disabled{background:linear-gradient(135deg,rgba(16,185,129,.4),rgba(5,150,105,.4));box-shadow:none}.auth-modal-light .btn-forgot-password{background:linear-gradient(135deg,#10b981,#059669)}.auth-modal-light .btn-forgot-password:hover{background:linear-gradient(135deg,#059669,#047857)}.auth-modal-light .btn-forgot-password .btn-arrow{filter:drop-shadow(0 0 4px rgba(255,255,255,.5))}.auth-modal-light .divider{color:rgba(0,0,0,.35)}.auth-modal-light .divider:after,.auth-modal-light .divider:before{background:linear-gradient(90deg,transparent,rgba(0,0,0,.1),transparent)}.auth-modal-light .btn-social,.auth-modal-light .btn-social-full{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 2px 4px rgba(0,0,0,.04),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#1a1a1a}.auth-modal-light .btn-social-full:hover,.auth-modal-light .btn-social:hover{background:#fff;border-color:rgba(16,185,129,.2);box-shadow:0 4px 8px rgba(0,0,0,.06),inset 0 0 0 1px rgba(16,185,129,.1);transform:translateY(-1px)}.auth-modal-light .btn-social-full:active,.auth-modal-light .btn-social:active{box-shadow:0 1px 3px rgba(0,0,0,.04),inset 0 0 0 1px rgba(0,0,0,.05);transform:translateY(0)}.auth-modal-light .link-primary{color:#10b981}.auth-modal-light .link-primary:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .forgot-password-icon{background:linear-gradient(135deg,rgba(16,185,129,.08),rgba(6,182,212,.06));box-shadow:0 8px 24px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .forgot-password-icon .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.15) 0,transparent 70%)}.auth-modal-light .forgot-password-icon .icon-lock{color:#10b981;filter:drop-shadow(0 2px 8px rgba(16,185,129,.2))}.auth-modal-light .forgot-password-icon .lock-shackle{animation:shakeLock 2s ease-in-out infinite}.auth-modal-light .back-to-login{color:rgba(0,0,0,.6)}.auth-modal-light .back-to-login:hover{color:#10b981}.auth-modal-light .back-to-login svg{color:rgba(0,0,0,.4)}.auth-modal-light .back-to-login:hover svg{color:#10b981}.auth-modal-light .auth-message-content{background:linear-gradient(135deg,rgba(16,185,129,.05),rgba(6,182,212,.03));box-shadow:0 8px 32px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .message-icon{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px rgba(16,185,129,.3),0 0 0 4px rgba(16,185,129,.1)}.auth-modal-light .message-icon svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.auth-modal-light .message-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .message-text{color:rgba(0,0,0,.6)}
|
|
1
|
+
:root{--font-display:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--color-neon-green:#10b981;--color-text-primary:#fff;--color-text-secondary:#a1a1aa;--color-text-tertiary:#71717a;--gradient-neon:linear-gradient(135deg,#10b981,#06b6d4)}.auth-modal{align-items:center;animation:modalFadeIn .3s ease-out;display:flex;inset:0;justify-content:center;overflow:hidden;padding:20px;position:fixed;z-index:9999}.auth-modal.hidden{display:none}@keyframes modalFadeIn{0%{opacity:0}to{opacity:1}}.auth-modal-backdrop{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:rgba(0,0,0,.85);inset:0;position:absolute}.auth-modal-content{animation:modalSlideUp .4s cubic-bezier(.4,0,.2,1);background:#0d0d0d;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 25px 80px rgba(0,0,0,.8);display:grid;grid-template-columns:1fr 1fr;max-height:90vh;max-width:900px;overflow:hidden;position:relative;transition:max-width .3s ease;width:100%;z-index:10}.auth-modal-content:has(#loginForm:not(.hidden)){grid-template-columns:1fr auto;max-width:none;width:auto}.auth-modal-content:has(#loginForm:not(.hidden)) .auth-modal-right{min-width:0;width:auto}.auth-modal-content:has(#authMessage:not(.hidden)){grid-template-columns:1fr;max-width:480px}.auth-modal-content:has(#authMessage:not(.hidden)) .auth-modal-left{display:none}@keyframes modalSlideUp{0%{opacity:0;transform:translateY(30px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.auth-modal-left{background:#000;border-right:1px solid hsla(0,0%,100%,.05);display:flex;flex-direction:column;overflow:hidden;padding:32px;position:relative}.auth-modal-left:before{animation:meshRotate 20s linear infinite;background:radial-gradient(at 0 0,rgba(99,102,241,.3) 0,transparent 50%),radial-gradient(at 50% 0,rgba(139,92,246,.3) 0,transparent 50%),radial-gradient(at 100% 0,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 0 50%,rgba(16,185,129,.3) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(244,63,94,.3) 0,transparent 50%),radial-gradient(at 0 100%,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(139,92,246,.3) 0,transparent 50%);content:"";filter:blur(80px);height:200%;inset:-50%;opacity:.6;position:absolute;width:200%}@keyframes meshRotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.65' numOctaves='3' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.05'/%3E%3C/svg%3E");content:"";inset:0;mix-blend-mode:overlay;opacity:.4;pointer-events:none;position:absolute}.auth-modal-logo{align-items:center;display:flex;gap:10px;position:relative;z-index:10}.auth-modal-logo .logo-icon{filter:drop-shadow(0 0 10px rgba(16,185,129,.3));height:28px;width:28px}.auth-modal-logo .logo-text{color:#fff;font-family:var(--font-display);font-size:18px;font-weight:700;text-shadow:0 0 20px rgba(0,0,0,.5)}.auth-modal-decoration{inset:0;overflow:hidden;pointer-events:none;position:absolute}.auth-modal-decoration .glow-orb-1{animation:breathe 8s ease-in-out infinite;background:radial-gradient(circle,hsla(0,0%,100%,.05) 0,transparent 70%);border-radius:50%;filter:blur(60px);height:400px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:400px}@keyframes breathe{0%,to{opacity:.5;transform:translate(-50%,-50%) scale(1)}50%{opacity:.8;transform:translate(-50%,-50%) scale(1.2)}}.auth-modal-decoration .glow-orb-2{animation:breathe 10s ease-in-out infinite;animation-delay:2s;background:radial-gradient(circle,rgba(139,92,246,.08) 0,transparent 70%);border-radius:50%;filter:blur(50px);height:300px;pointer-events:none;position:absolute;right:-10%;top:20%;width:300px}.auth-modal-branding{margin-bottom:48px;margin-top:auto;position:relative;z-index:10}.auth-modal-branding .branding-title{color:#fff;font-family:var(--font-display);font-size:36px;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:12px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.auth-modal-branding .branding-subtitle{color:hsla(0,0%,100%,.8);font-size:14px;line-height:1.6;max-width:260px}.auth-modal-right{background:#121212;display:flex;flex-direction:column;max-height:90vh;overflow-y:auto;padding:56px 48px 42px;position:relative}.auth-modal-right::-webkit-scrollbar{width:6px}.auth-modal-right::-webkit-scrollbar-track{background:transparent}.auth-modal-right::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.1);border-radius:3px}.auth-modal-close{align-items:center;background:transparent;border:none;border-radius:8px;color:hsla(0,0%,100%,.5);cursor:pointer;display:flex;height:36px;justify-content:center;position:absolute;right:16px;top:16px;transition:all .2s ease;width:36px;z-index:20}.auth-modal-close:hover{background:hsla(0,0%,100%,.1);color:#fff}.auth-form-view{animation:formFadeIn .3s ease-out}#loginForm .form-input{width:360px}@keyframes formFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.auth-form-view.hidden{display:none}.auth-form-header{margin-bottom:28px;text-align:center}.auth-form-title{color:#fff;font-family:var(--font-display);font-size:26px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}.auth-form-subtitle{color:var(--color-text-secondary);font-size:14px}.auth-form{gap:16px}.auth-form,.form-group{display:flex;flex-direction:column}.form-group{gap:6px}.form-label{font-size:12px;font-weight:500;letter-spacing:.02em;opacity:.9;text-transform:uppercase}.form-input,.form-label{color:var(--color-text-primary)}.form-input{background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:8px;font-family:var(--font-sans);font-size:14px;height:40px;outline:none;padding:0 14px;transition:all .2s ease;width:100%}.form-input::placeholder{color:hsla(0,0%,100%,.35)}.form-input:hover{border-color:hsla(0,0%,100%,.15)}.form-input:focus{background:rgba(30,30,30,.9);border-color:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.15)}.form-input:invalid:not(:placeholder-shown){border-color:#ff006e}.form-input[type=textarea],textarea.form-input{font-family:inherit;line-height:1.5;min-height:100px;padding:12px 14px;resize:vertical}.char-count{color:hsla(0,0%,100%,.5);font-size:12px;margin-top:4px;text-align:right}.auth-modal-light .char-count{color:rgba(0,0,0,.4)}.icon-mail{animation:floatIcon 4s ease-in-out infinite;color:#10b981;filter:drop-shadow(0 0 10px rgba(16,185,129,.4));position:relative;z-index:2}.forgot-password-icon:has(.icon-mail) .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.25) 0,rgba(6,182,212,.15) 40%,transparent 70%)}#applyInviteReason{background:hsla(0,0%,8%,.6);min-height:120px;padding:14px 16px;position:relative;transition:all .3s ease}#applyInviteReason:focus{background:hsla(0,0%,8%,.8);border-color:rgba(16,185,129,.5);box-shadow:0 0 0 3px rgba(16,185,129,.15),0 0 20px rgba(16,185,129,.15),inset 0 1px 0 hsla(0,0%,100%,.05)}.form-group:has(#applyInviteReason) .char-count{color:hsla(240,5%,65%,.7);display:block;float:right;font-size:12px;font-variant-numeric:tabular-nums;font-weight:600;letter-spacing:.02em;margin-top:8px;padding:4px 0;position:relative;text-align:right;transition:all .3s ease}.form-group:has(#applyInviteReason) .char-count:before{background:linear-gradient(90deg,#10b981,#06b6d4);bottom:0;box-shadow:0 0 8px rgba(16,185,129,.5);content:"";height:2px;left:0;position:absolute;transition:width .3s ease,box-shadow .3s ease,background .3s ease;width:var(--progress-width,0)}.form-group:has(#applyInviteReason) .char-count[data-progress=low]{color:rgba(251,191,36,.9)}.form-group:has(#applyInviteReason) .char-count[data-progress=low]:before{background:linear-gradient(90deg,rgba(251,191,36,.8),rgba(251,191,36,.6));box-shadow:0 0 8px rgba(251,191,36,.5)}.form-group:has(#applyInviteReason) .char-count[data-progress=medium]{color:rgba(16,185,129,.9)}.form-group:has(#applyInviteReason) .char-count[data-progress=medium]:before{background:linear-gradient(90deg,#10b981,#06b6d4);box-shadow:0 0 10px rgba(16,185,129,.6)}.form-group:has(#applyInviteReason) .char-count[data-progress=high]{color:rgba(239,68,68,.9)}.form-group:has(#applyInviteReason) .char-count[data-progress=high]:before{background:linear-gradient(90deg,rgba(239,68,68,.8),rgba(239,68,68,.6));box-shadow:0 0 10px rgba(239,68,68,.6)}.auth-modal-light .icon-mail{color:#059669;filter:drop-shadow(0 0 8px rgba(5,150,105,.3))}.auth-modal-light .forgot-password-icon:has(.icon-mail) .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.15) 0,rgba(6,182,212,.1) 40%,transparent 70%)}.auth-modal-light #applyInviteReason{background:hsla(0,0%,100%,.8);border-color:rgba(16,185,129,.2);color:#0a0a0a}.auth-modal-light #applyInviteReason:focus{background:hsla(0,0%,100%,.95);border-color:rgba(16,185,129,.5);box-shadow:0 0 0 3px rgba(16,185,129,.12),0 0 20px rgba(16,185,129,.1),inset 0 1px 0 hsla(0,0%,100%,.8)}.auth-modal-light .form-group:has(#applyInviteReason) .char-count{color:rgba(82,82,91,.8)}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon .form-input{padding-right:40px}.input-icon-btn{align-items:center;background:transparent;border:none;border-radius:4px;color:hsla(0,0%,100%,.4);cursor:pointer;display:flex;justify-content:center;padding:6px;position:absolute;right:8px;transition:color .2s ease}.input-icon-btn:hover{background:hsla(0,0%,100%,.05);color:hsla(0,0%,100%,.7)}.input-icon-btn .hidden{display:none}.strength-text{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:12px;font-weight:500;gap:6px;margin-top:4px}.form-group-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:8px}.form-group-header .form-label{margin-bottom:0}.forgot-password-link{color:hsla(0,0%,100%,.5);font-size:13px;font-weight:500;position:relative;text-decoration:none;transition:all .25s ease}.forgot-password-link:after{background:#10b981;bottom:-2px;content:"";height:1px;left:0;position:absolute;transition:width .3s ease;width:0}.forgot-password-link:hover{color:#10b981}.forgot-password-link:hover:after{width:100%}.link-primary{color:var(--color-neon-green);font-weight:600;position:relative;text-decoration:none;text-shadow:0 0 10px rgba(0,255,136,.3);transition:all .2s ease}.link-primary:after{background:var(--color-neon-green);bottom:-2px;content:"";height:1px;left:0;position:absolute;transform:scaleX(0);transform-origin:right;transition:transform .3s ease;width:100%}.link-primary:hover{color:#0f8;text-shadow:0 0 20px rgba(0,255,136,.5)}.link-primary:hover:after{transform:scaleX(1);transform-origin:left}.btn-auth-primary{align-items:center;background:var(--gradient-neon);border:none;border-radius:10px;box-shadow:0 4px 12px rgba(16,185,129,.25);color:#000;cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:600;gap:8px;height:44px;justify-content:center;margin-top:8px;overflow:hidden;padding:0 24px;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);width:100%}.btn-auth-primary:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.2) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-auth-primary:hover{box-shadow:0 8px 20px rgba(16,185,129,.35);transform:translateY(-2px)}.btn-auth-primary:hover:before{opacity:1}.btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.25);transform:translateY(0)}.btn-auth-primary:disabled{cursor:not-allowed;opacity:.6;transform:none}.btn-auth-primary .btn-text{position:relative;z-index:2}.btn-auth-primary .btn-loader{align-items:center;display:flex;justify-content:center;position:relative;z-index:2}.btn-auth-primary .btn-loader.hidden{display:none}.spinner{animation:spin .8s linear infinite;fill:none;height:20px;stroke-width:3;width:20px}@keyframes spin{to{transform:rotate(1turn)}}.spinner-track{stroke:rgba(0,0,0,.2)}.spinner-circle{animation:spinDash 1.2s ease-in-out infinite;stroke:#000;stroke-dasharray:50;stroke-dashoffset:50}@keyframes spinDash{0%{stroke-dashoffset:50}50%{stroke-dashoffset:12.5}to{stroke-dashoffset:50}}.forgot-password-icon{align-items:center;display:flex;height:100px;justify-content:center;margin:0 auto 24px;position:relative;width:100px}.forgot-password-icon .icon-glow{animation:pulseGlow 3s ease-in-out infinite;background:radial-gradient(circle,rgba(16,185,129,.25) 0,transparent 70%);border-radius:50%;filter:blur(15px);inset:-10px;position:absolute}@keyframes pulseGlow{0%,to{opacity:.5;transform:scale(.95)}50%{opacity:.8;transform:scale(1.05)}}.forgot-password-icon .icon-lock{animation:floatIcon 4s ease-in-out infinite;color:#10b981;filter:drop-shadow(0 0 10px rgba(16,185,129,.4));position:relative;z-index:2}@keyframes floatIcon{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.btn-forgot-password{align-items:center;display:flex;gap:8px;justify-content:center}.btn-forgot-password .btn-arrow{transition:transform .3s ease}.btn-forgot-password:hover .btn-arrow{transform:translateX(4px)}.auth-footer{margin-top:24px;text-align:center}.forgot-footer{display:flex;justify-content:center}.back-to-login{align-items:center;border-radius:6px;color:var(--color-text-secondary);display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:8px 12px;text-decoration:none;transition:all .2s ease}.back-to-login:hover{background:rgba(16,185,129,.05);color:var(--color-neon-green)}.back-to-login svg{transition:transform .3s ease}.back-to-login:hover svg{transform:translateX(-4px)}.auth-footer-divider{isolation:isolate;margin-top:32px;padding:28px 20px 0;position:relative;text-align:center}.auth-footer-divider:before{animation:energyFlow 4s ease-in-out infinite;background:linear-gradient(90deg,transparent,rgba(16,185,129,.15) 15%,rgba(16,185,129,.5) 30%,rgba(6,182,212,.6) 50%,rgba(16,185,129,.5) 70%,rgba(16,185,129,.15) 85%,transparent);filter:blur(.5px);height:2px;top:0;width:85%}.auth-footer-divider:after,.auth-footer-divider:before{content:"";left:50%;position:absolute;transform:translateX(-50%)}.auth-footer-divider:after{animation:glowPulse 3s ease-in-out infinite;background:radial-gradient(ellipse at center,rgba(16,185,129,.25) 0,rgba(6,182,212,.15) 40%,transparent 70%);filter:blur(6px);height:8px;opacity:.6;top:-4px;width:70%}@keyframes energyFlow{0%,to{opacity:.7;transform:translateX(-50%) scaleX(1)}50%{opacity:1;transform:translateX(-50%) scaleX(1.02)}}@keyframes glowPulse{0%,to{opacity:.4;transform:translateX(-50%) scaleY(.8)}50%{opacity:.8;transform:translateX(-50%) scaleY(1.2)}}.auth-footer-text{color:hsla(240,5%,65%,.85);font-size:13.5px;font-weight:400;letter-spacing:.02em;line-height:1.6;margin:0;position:relative;z-index:1}.auth-link{background:rgba(16,185,129,.05);border:1px solid rgba(16,185,129,.2);border-radius:6px;color:#10b981;display:inline-block;font-weight:600;isolation:isolate;letter-spacing:.01em;margin-left:6px;padding:6px 14px;position:relative;text-decoration:none;transition:all .4s cubic-bezier(.34,1.56,.64,1)}.auth-link:before{animation:shimmerRotate 3s linear infinite paused;background:linear-gradient(135deg,transparent,rgba(16,185,129,.4) 25%,rgba(6,182,212,.5) 50%,rgba(16,185,129,.4) 75%,transparent);border-radius:6px;content:"";inset:-1px;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask-composite:exclude;opacity:0;padding:1px;position:absolute;transition:opacity .4s ease}@keyframes shimmerRotate{0%{background-position:0 50%}to{background-position:200% 50%}}.auth-link:after{background:linear-gradient(90deg,rgba(16,185,129,.8),rgba(6,182,212,.9),rgba(16,185,129,.8));border-radius:2px;bottom:3px;box-shadow:0 0 8px rgba(16,185,129,.6),0 0 12px rgba(6,182,212,.4);content:"";filter:blur(.5px);height:2px;left:14px;position:absolute;right:14px;transform:scaleX(0);transform-origin:center;transition:transform .4s cubic-bezier(.34,1.56,.64,1)}.auth-link:hover{background:rgba(16,185,129,.12);border-color:rgba(6,182,212,.5);box-shadow:0 4px 20px rgba(16,185,129,.3),0 0 40px rgba(6,182,212,.15),inset 0 1px 0 hsla(0,0%,100%,.1);color:#0fa;text-shadow:0 0 10px rgba(16,185,129,.6),0 0 20px rgba(6,182,212,.4),0 0 30px rgba(16,185,129,.2);transform:translateY(-2px) scale(1.02)}.auth-link:hover:before{animation-play-state:running;opacity:1}.auth-link:hover:after{transform:scaleX(1)}.auth-link:active{background:rgba(16,185,129,.18);border-color:rgba(16,185,129,.6);box-shadow:0 2px 12px rgba(16,185,129,.4),inset 0 2px 8px rgba(0,0,0,.2);transform:translateY(0) scale(.98)}.auth-link:focus-visible{border-color:rgba(16,185,129,.8);box-shadow:0 0 0 3px rgba(16,185,129,.3),0 0 20px rgba(16,185,129,.4),inset 0 1px 0 hsla(0,0%,100%,.15);outline:none}@media (max-width:768px){.auth-footer-divider{margin-top:28px;padding-top:24px}.auth-footer-divider:before{width:90%}.auth-footer-text{font-size:13px}.auth-link{margin-left:4px;padding:8px 16px}.auth-link:after{left:16px;right:16px}}.auth-modal-light .auth-footer-divider:before{background:linear-gradient(90deg,transparent,rgba(16,185,129,.2) 15%,rgba(16,185,129,.35) 30%,rgba(6,182,212,.4) 50%,rgba(16,185,129,.35) 70%,rgba(16,185,129,.2) 85%,transparent)}.auth-modal-light .auth-footer-divider:after{background:radial-gradient(ellipse at center,rgba(16,185,129,.15) 0,rgba(6,182,212,.1) 40%,transparent 70%)}.auth-modal-light .auth-footer-text{color:rgba(82,82,91,.9)}.auth-modal-light .auth-link{background:rgba(16,185,129,.08);border-color:rgba(16,185,129,.25);color:#059669}.auth-modal-light .auth-link:before{background:linear-gradient(135deg,transparent,rgba(16,185,129,.5) 25%,rgba(6,182,212,.6) 50%,rgba(16,185,129,.5) 75%,transparent)}.auth-modal-light .auth-link:hover{background:rgba(16,185,129,.15);border-color:rgba(6,182,212,.4);box-shadow:0 4px 16px rgba(16,185,129,.25),0 0 30px rgba(6,182,212,.1),inset 0 1px 0 hsla(0,0%,100%,.6);color:#047857;text-shadow:0 0 8px rgba(16,185,129,.4),0 0 16px rgba(6,182,212,.3)}.auth-modal-light .auth-link:active{background:rgba(16,185,129,.22);box-shadow:0 2px 10px rgba(16,185,129,.3),inset 0 2px 6px rgba(0,0,0,.1)}.auth-message-content{align-items:center;display:flex;flex-direction:column;padding:24px;text-align:center}.message-icon{align-items:center;background:rgba(16,185,129,.1);border-radius:50%;color:#10b981;display:flex;height:80px;justify-content:center;margin-bottom:24px;width:80px}.message-icon svg{animation:successPulse 2s ease-in-out infinite;filter:drop-shadow(0 0 10px rgba(16,185,129,.3))}@keyframes successPulse{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}.message-title{color:#fff;font-family:var(--font-display);font-size:24px;font-weight:700;margin-bottom:12px}.message-text{color:var(--color-text-secondary);font-size:14px;line-height:1.6;margin-bottom:24px}.divider{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:11px;font-weight:600;gap:12px;letter-spacing:.08em;margin:24px 0 20px;position:relative;text-align:center}.divider:after,.divider:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.1),transparent);content:"";flex:1;height:1px}.social-buttons-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr}.btn-social{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;margin:0;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1)}.btn-social:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social:hover:before{opacity:1}.btn-social:active{transform:translateY(0)}.btn-social svg{flex-shrink:0;height:20px;width:20px}.btn-social span{position:relative;white-space:nowrap;z-index:2}.btn-social-full{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1);width:100%}.btn-social-full:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social-full:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social-full:hover:before{opacity:1}.btn-social-full:active{transform:translateY(0)}.btn-social-full svg{flex-shrink:0;height:20px;width:20px}.btn-social-full span{position:relative;z-index:2}@media (max-width:768px){.auth-modal-content{border-radius:0;grid-template-columns:1fr;max-height:100vh;max-width:100%}.auth-modal-left{display:none}.auth-modal-right{max-height:100vh;padding:24px}.auth-form-title{font-size:22px}#loginForm .form-input{width:100%}.btn-auth-primary{font-size:15px;height:48px}.social-buttons-grid{gap:10px;grid-template-columns:1fr}.btn-social,.btn-social-full{height:48px}}@media (max-width:480px){.auth-modal{padding:0}.auth-modal-content{border-radius:0;max-height:100vh}.auth-modal-right{padding:20px 16px}.auth-form-header{margin-bottom:20px}}.auth-modal-light .auth-modal-backdrop{backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);background:hsla(0,0%,100%,.75)}.auth-modal-light .auth-modal-content{background:linear-gradient(135deg,#fdfbf7,#f8f6f2);border:1px solid rgba(16,185,129,.1);box-shadow:0 50px 100px rgba(0,0,0,.12),0 20px 40px rgba(0,0,0,.08),inset 0 0 0 1px hsla(0,0%,100%,.9)}.auth-modal-light .auth-modal-left{background:linear-gradient(135deg,#fff,#faf9f7);border-right:1px solid rgba(16,185,129,.08);box-shadow:2px 0 20px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .auth-modal-left:before{background:radial-gradient(at 0 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 50% 0,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 100% 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 0 50%,rgba(52,211,153,.05) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 0 100%,rgba(16,185,129,.07) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(52,211,153,.06) 0,transparent 50%);filter:blur(60px);opacity:.9}.auth-modal-light .auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.02'/%3E%3C/svg%3E");mix-blend-mode:multiply;opacity:.6}.auth-modal-light .auth-modal-logo .logo-icon{filter:drop-shadow(0 2px 8px rgba(16,185,129,.25))}.auth-modal-light .auth-modal-logo .logo-text{color:#0a0a0a;text-shadow:0 1px 2px rgba(16,185,129,.1)}.auth-modal-light .auth-modal-decoration .glow-orb-1{background:radial-gradient(circle,rgba(16,185,129,.08) 0,transparent 70%);filter:blur(80px)}.auth-modal-light .auth-modal-decoration .glow-orb-2{background:radial-gradient(circle,rgba(6,182,212,.06) 0,transparent 70%);filter:blur(70px)}.auth-modal-light .auth-modal-branding .branding-title{background:linear-gradient(135deg,#0a0a0a,#1a1a1a);-webkit-background-clip:text;color:#0a0a0a;text-shadow:0 2px 12px rgba(16,185,129,.12);-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-modal-branding .branding-subtitle{color:rgba(0,0,0,.6)}.auth-modal-light .auth-modal-right{backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);background:hsla(0,0%,100%,.85);box-shadow:-2px 0 20px rgba(0,0,0,.03)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb{background:rgba(16,185,129,.2)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb:hover{background:rgba(16,185,129,.3)}.auth-modal-light .auth-modal-close{color:rgba(0,0,0,.4)}.auth-modal-light .auth-modal-close:hover{background:rgba(16,185,129,.08);color:#0a0a0a}.auth-modal-light .auth-form-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-form-subtitle{color:rgba(0,0,0,.5)}.auth-modal-light .form-label{color:#0a0a0a;opacity:.7}.auth-modal-light .form-input{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 1px 2px rgba(0,0,0,.02),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#0a0a0a}.auth-modal-light .form-input::placeholder{color:rgba(0,0,0,.3)}.auth-modal-light .form-input:hover{border-color:rgba(16,185,129,.2);box-shadow:0 2px 4px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .form-input:focus{background:#fff;border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.12),0 2px 8px rgba(16,185,129,.08)}.auth-modal-light .form-input:invalid:not(:placeholder-shown){border-color:#ff006e;box-shadow:0 0 0 3px rgba(255,0,110,.1)}.auth-modal-light .input-icon-btn{color:rgba(0,0,0,.4)}.auth-modal-light .input-icon-btn:hover{color:rgba(0,0,0,.7)}.auth-modal-light .forgot-password-link{color:#10b981}.auth-modal-light .forgot-password-link:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .strength-text{color:rgba(0,0,0,.45)}.auth-modal-light .btn-auth-primary{background:linear-gradient(135deg,#10b981,#059669);border:none;box-shadow:0 4px 12px rgba(16,185,129,.25),0 2px 4px rgba(16,185,129,.15),inset 0 0 0 1px hsla(0,0%,100%,.3);color:#fff}.auth-modal-light .btn-auth-primary:hover{background:linear-gradient(135deg,#059669,#047857);box-shadow:0 6px 16px rgba(16,185,129,.3),0 3px 6px rgba(16,185,129,.2),inset 0 0 0 1px hsla(0,0%,100%,.4);transform:translateY(-1px)}.auth-modal-light .btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.2),0 1px 3px rgba(16,185,129,.15);transform:translateY(0)}.auth-modal-light .btn-auth-primary:disabled{background:linear-gradient(135deg,rgba(16,185,129,.4),rgba(5,150,105,.4));box-shadow:none}.auth-modal-light .btn-forgot-password{background:linear-gradient(135deg,#10b981,#059669)}.auth-modal-light .btn-forgot-password:hover{background:linear-gradient(135deg,#059669,#047857)}.auth-modal-light .btn-forgot-password .btn-arrow{filter:drop-shadow(0 0 4px rgba(255,255,255,.5))}.auth-modal-light .divider{color:rgba(0,0,0,.35)}.auth-modal-light .divider:after,.auth-modal-light .divider:before{background:linear-gradient(90deg,transparent,rgba(0,0,0,.1),transparent)}.auth-modal-light .btn-social,.auth-modal-light .btn-social-full{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 2px 4px rgba(0,0,0,.04),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#1a1a1a}.auth-modal-light .btn-social-full:hover,.auth-modal-light .btn-social:hover{background:#fff;border-color:rgba(16,185,129,.2);box-shadow:0 4px 8px rgba(0,0,0,.06),inset 0 0 0 1px rgba(16,185,129,.1);transform:translateY(-1px)}.auth-modal-light .btn-social-full:active,.auth-modal-light .btn-social:active{box-shadow:0 1px 3px rgba(0,0,0,.04),inset 0 0 0 1px rgba(0,0,0,.05);transform:translateY(0)}.auth-modal-light .link-primary{color:#10b981}.auth-modal-light .link-primary:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .forgot-password-icon{background:linear-gradient(135deg,rgba(16,185,129,.08),rgba(6,182,212,.06));box-shadow:0 8px 24px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .forgot-password-icon .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.15) 0,transparent 70%)}.auth-modal-light .forgot-password-icon .icon-lock{color:#10b981;filter:drop-shadow(0 2px 8px rgba(16,185,129,.2))}.auth-modal-light .forgot-password-icon .lock-shackle{animation:shakeLock 2s ease-in-out infinite}.auth-modal-light .back-to-login{color:rgba(0,0,0,.6)}.auth-modal-light .back-to-login:hover{color:#10b981}.auth-modal-light .back-to-login svg{color:rgba(0,0,0,.4)}.auth-modal-light .back-to-login:hover svg{color:#10b981}.auth-modal-light .auth-message-content{background:linear-gradient(135deg,rgba(16,185,129,.05),rgba(6,182,212,.03));box-shadow:0 8px 32px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .message-icon{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px rgba(16,185,129,.3),0 0 0 4px rgba(16,185,129,.1)}.auth-modal-light .message-icon svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.auth-modal-light .message-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .message-text{color:rgba(0,0,0,.6)}
|
package/dist/index.cjs
CHANGED
|
@@ -1660,6 +1660,43 @@ class SeaVerseBackendAPIClient {
|
|
|
1660
1660
|
const response = await this.httpClient.request(config);
|
|
1661
1661
|
return response.data;
|
|
1662
1662
|
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Submit invite application
|
|
1665
|
+
* Apply for an invitation code by submitting email and reason
|
|
1666
|
+
*
|
|
1667
|
+
* @param data - Invite application request
|
|
1668
|
+
* @param options - Additional axios request options
|
|
1669
|
+
* @returns Application submission response
|
|
1670
|
+
*
|
|
1671
|
+
* @example
|
|
1672
|
+
* // Submit invite application
|
|
1673
|
+
* const result = await client.applyInvite({
|
|
1674
|
+
* email: 'player@example.com',
|
|
1675
|
+
* reason: 'I want to join this amazing platform to build innovative applications.'
|
|
1676
|
+
* });
|
|
1677
|
+
*
|
|
1678
|
+
* if (result.success) {
|
|
1679
|
+
* console.log('Application submitted:', result.data);
|
|
1680
|
+
* console.log('Application ID:', result.data.id);
|
|
1681
|
+
* console.log('Status:', result.data.status); // 'pending'
|
|
1682
|
+
* } else {
|
|
1683
|
+
* console.error('Application failed:', result.error);
|
|
1684
|
+
* }
|
|
1685
|
+
*/
|
|
1686
|
+
async applyInvite(data, options) {
|
|
1687
|
+
const config = {
|
|
1688
|
+
method: 'POST',
|
|
1689
|
+
url: `/sdk/v1/auth/apply-invite`,
|
|
1690
|
+
data,
|
|
1691
|
+
headers: {
|
|
1692
|
+
'X-Operation-Id': 'applyInvite',
|
|
1693
|
+
...options?.headers,
|
|
1694
|
+
},
|
|
1695
|
+
...options,
|
|
1696
|
+
};
|
|
1697
|
+
const response = await this.httpClient.request(config);
|
|
1698
|
+
return response.data;
|
|
1699
|
+
}
|
|
1663
1700
|
// ============================================================================
|
|
1664
1701
|
// OAuth APIs
|
|
1665
1702
|
// ============================================================================
|
|
@@ -2714,6 +2751,9 @@ class AuthModal {
|
|
|
2714
2751
|
// Invite code form
|
|
2715
2752
|
const inviteCodeForm = this.createInviteCodeForm();
|
|
2716
2753
|
rightPanel.appendChild(inviteCodeForm);
|
|
2754
|
+
// Apply invite form
|
|
2755
|
+
const applyInviteForm = this.createApplyInviteForm();
|
|
2756
|
+
rightPanel.appendChild(applyInviteForm);
|
|
2717
2757
|
// Success message
|
|
2718
2758
|
const successMessage = this.createSuccessMessage();
|
|
2719
2759
|
rightPanel.appendChild(successMessage);
|
|
@@ -3089,6 +3129,21 @@ class AuthModal {
|
|
|
3089
3129
|
submitBtn.appendChild(btnLoader);
|
|
3090
3130
|
form.appendChild(submitBtn);
|
|
3091
3131
|
container.appendChild(form);
|
|
3132
|
+
// Apply invite link
|
|
3133
|
+
const applyInviteSection = document.createElement('div');
|
|
3134
|
+
applyInviteSection.className = 'auth-footer-divider';
|
|
3135
|
+
const applyInviteText = document.createElement('p');
|
|
3136
|
+
applyInviteText.className = 'auth-footer-text';
|
|
3137
|
+
applyInviteText.textContent = "Don't have an invitation code?";
|
|
3138
|
+
const applyInviteLink = document.createElement('a');
|
|
3139
|
+
applyInviteLink.href = '#';
|
|
3140
|
+
applyInviteLink.id = 'showApplyInviteForm';
|
|
3141
|
+
applyInviteLink.className = 'auth-link';
|
|
3142
|
+
applyInviteLink.textContent = 'Apply for one';
|
|
3143
|
+
applyInviteText.appendChild(document.createTextNode(' '));
|
|
3144
|
+
applyInviteText.appendChild(applyInviteLink);
|
|
3145
|
+
applyInviteSection.appendChild(applyInviteText);
|
|
3146
|
+
container.appendChild(applyInviteSection);
|
|
3092
3147
|
// Footer
|
|
3093
3148
|
const footer = document.createElement('div');
|
|
3094
3149
|
footer.className = 'auth-footer forgot-footer';
|
|
@@ -3101,6 +3156,84 @@ class AuthModal {
|
|
|
3101
3156
|
container.appendChild(footer);
|
|
3102
3157
|
return container;
|
|
3103
3158
|
}
|
|
3159
|
+
createApplyInviteForm() {
|
|
3160
|
+
const container = document.createElement('div');
|
|
3161
|
+
container.id = 'applyInviteForm';
|
|
3162
|
+
container.className = 'auth-form-view hidden';
|
|
3163
|
+
// Icon
|
|
3164
|
+
const icon = document.createElement('div');
|
|
3165
|
+
icon.className = 'forgot-password-icon';
|
|
3166
|
+
icon.innerHTML = '<div class="icon-glow"></div><svg class="icon-mail" width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>';
|
|
3167
|
+
container.appendChild(icon);
|
|
3168
|
+
// Header
|
|
3169
|
+
const header = document.createElement('div');
|
|
3170
|
+
header.className = 'auth-form-header';
|
|
3171
|
+
const title = document.createElement('h2');
|
|
3172
|
+
title.className = 'auth-form-title';
|
|
3173
|
+
title.textContent = 'Apply for Invitation Code';
|
|
3174
|
+
const subtitle = document.createElement('p');
|
|
3175
|
+
subtitle.className = 'auth-form-subtitle';
|
|
3176
|
+
subtitle.textContent = 'Tell us why you want to join our platform';
|
|
3177
|
+
header.appendChild(title);
|
|
3178
|
+
header.appendChild(subtitle);
|
|
3179
|
+
container.appendChild(header);
|
|
3180
|
+
// Form
|
|
3181
|
+
const form = document.createElement('form');
|
|
3182
|
+
form.id = 'applyInviteFormElement';
|
|
3183
|
+
form.className = 'auth-form';
|
|
3184
|
+
// Email input
|
|
3185
|
+
const emailGroup = this.createFormGroup('applyInviteEmail', 'Email', 'email', 'Enter your email');
|
|
3186
|
+
form.appendChild(emailGroup);
|
|
3187
|
+
// Reason textarea
|
|
3188
|
+
const reasonGroup = document.createElement('div');
|
|
3189
|
+
reasonGroup.className = 'form-group';
|
|
3190
|
+
const reasonLabel = document.createElement('label');
|
|
3191
|
+
reasonLabel.htmlFor = 'applyInviteReason';
|
|
3192
|
+
reasonLabel.className = 'form-label';
|
|
3193
|
+
reasonLabel.textContent = 'Reason';
|
|
3194
|
+
reasonGroup.appendChild(reasonLabel);
|
|
3195
|
+
const reasonTextarea = document.createElement('textarea');
|
|
3196
|
+
reasonTextarea.id = 'applyInviteReason';
|
|
3197
|
+
reasonTextarea.name = 'reason';
|
|
3198
|
+
reasonTextarea.className = 'form-input';
|
|
3199
|
+
reasonTextarea.placeholder = 'Tell us a bit about yourself and what brings you here...';
|
|
3200
|
+
reasonTextarea.rows = 4;
|
|
3201
|
+
reasonTextarea.required = true;
|
|
3202
|
+
reasonTextarea.minLength = 10;
|
|
3203
|
+
reasonTextarea.maxLength = 500;
|
|
3204
|
+
reasonGroup.appendChild(reasonTextarea);
|
|
3205
|
+
const charCount = document.createElement('div');
|
|
3206
|
+
charCount.className = 'char-count';
|
|
3207
|
+
charCount.textContent = '0/500';
|
|
3208
|
+
reasonGroup.appendChild(charCount);
|
|
3209
|
+
form.appendChild(reasonGroup);
|
|
3210
|
+
// Submit button
|
|
3211
|
+
const submitBtn = document.createElement('button');
|
|
3212
|
+
submitBtn.type = 'submit';
|
|
3213
|
+
submitBtn.id = 'applyInviteButton';
|
|
3214
|
+
submitBtn.className = 'btn-auth-primary';
|
|
3215
|
+
const btnText = document.createElement('span');
|
|
3216
|
+
btnText.className = 'btn-text';
|
|
3217
|
+
btnText.textContent = 'Submit Application';
|
|
3218
|
+
const btnLoader = document.createElement('span');
|
|
3219
|
+
btnLoader.className = 'btn-loader hidden';
|
|
3220
|
+
btnLoader.innerHTML = '<svg class="spinner" viewBox="0 0 24 24"><circle class="spinner-track" cx="12" cy="12" r="10"></circle><circle class="spinner-circle" cx="12" cy="12" r="10"></circle></svg>';
|
|
3221
|
+
submitBtn.appendChild(btnText);
|
|
3222
|
+
submitBtn.appendChild(btnLoader);
|
|
3223
|
+
form.appendChild(submitBtn);
|
|
3224
|
+
container.appendChild(form);
|
|
3225
|
+
// Footer
|
|
3226
|
+
const footer = document.createElement('div');
|
|
3227
|
+
footer.className = 'auth-footer forgot-footer';
|
|
3228
|
+
const backLink = document.createElement('a');
|
|
3229
|
+
backLink.href = '#';
|
|
3230
|
+
backLink.id = 'backToInviteCodeFromApply';
|
|
3231
|
+
backLink.className = 'back-to-login';
|
|
3232
|
+
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 Enter Code</span>';
|
|
3233
|
+
footer.appendChild(backLink);
|
|
3234
|
+
container.appendChild(footer);
|
|
3235
|
+
return container;
|
|
3236
|
+
}
|
|
3104
3237
|
createSuccessMessage() {
|
|
3105
3238
|
const container = document.createElement('div');
|
|
3106
3239
|
container.id = 'authMessage';
|
|
@@ -3343,6 +3476,16 @@ class AuthModal {
|
|
|
3343
3476
|
e.preventDefault();
|
|
3344
3477
|
this.switchView('login');
|
|
3345
3478
|
});
|
|
3479
|
+
const showApplyInviteForm = this.modal.querySelector('#showApplyInviteForm');
|
|
3480
|
+
showApplyInviteForm?.addEventListener('click', (e) => {
|
|
3481
|
+
e.preventDefault();
|
|
3482
|
+
this.switchView('apply-invite');
|
|
3483
|
+
});
|
|
3484
|
+
const backToInviteCodeFromApply = this.modal.querySelector('#backToInviteCodeFromApply');
|
|
3485
|
+
backToInviteCodeFromApply?.addEventListener('click', (e) => {
|
|
3486
|
+
e.preventDefault();
|
|
3487
|
+
this.switchView('invite-code');
|
|
3488
|
+
});
|
|
3346
3489
|
// Password toggle
|
|
3347
3490
|
const passwordToggles = this.modal.querySelectorAll('.toggle-password');
|
|
3348
3491
|
passwordToggles.forEach((toggle) => {
|
|
@@ -3377,6 +3520,32 @@ class AuthModal {
|
|
|
3377
3520
|
resetPasswordForm?.addEventListener('submit', (e) => this.handleResetPassword(e));
|
|
3378
3521
|
const inviteCodeForm = this.modal.querySelector('#inviteCodeFormElement');
|
|
3379
3522
|
inviteCodeForm?.addEventListener('submit', (e) => this.handleBindInviteCode(e));
|
|
3523
|
+
const applyInviteForm = this.modal.querySelector('#applyInviteFormElement');
|
|
3524
|
+
applyInviteForm?.addEventListener('submit', (e) => this.handleApplyInvite(e));
|
|
3525
|
+
// Character counter for reason textarea with dynamic progress
|
|
3526
|
+
const reasonTextarea = this.modal.querySelector('#applyInviteReason');
|
|
3527
|
+
const charCount = this.modal.querySelector('.char-count');
|
|
3528
|
+
reasonTextarea?.addEventListener('input', () => {
|
|
3529
|
+
if (charCount) {
|
|
3530
|
+
const length = reasonTextarea.value.length;
|
|
3531
|
+
const maxLength = 500;
|
|
3532
|
+
const percentage = (length / maxLength) * 100;
|
|
3533
|
+
// Update text
|
|
3534
|
+
charCount.textContent = `${length}/${maxLength}`;
|
|
3535
|
+
// Update progress bar width
|
|
3536
|
+
charCount.style.setProperty('--progress-width', `${percentage}%`);
|
|
3537
|
+
// Update progress state
|
|
3538
|
+
if (length < 100) {
|
|
3539
|
+
charCount.setAttribute('data-progress', 'low');
|
|
3540
|
+
}
|
|
3541
|
+
else if (length < 400) {
|
|
3542
|
+
charCount.setAttribute('data-progress', 'medium');
|
|
3543
|
+
}
|
|
3544
|
+
else {
|
|
3545
|
+
charCount.setAttribute('data-progress', 'high');
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
});
|
|
3380
3549
|
// OAuth social login buttons
|
|
3381
3550
|
this.bindSocialLoginButtons();
|
|
3382
3551
|
}
|
|
@@ -3423,7 +3592,7 @@ class AuthModal {
|
|
|
3423
3592
|
switchView(view) {
|
|
3424
3593
|
if (!this.modal)
|
|
3425
3594
|
return;
|
|
3426
|
-
const views = ['loginForm', 'signupForm', 'forgotPasswordForm', 'resetPasswordForm', 'inviteCodeForm', 'authMessage'];
|
|
3595
|
+
const views = ['loginForm', 'signupForm', 'forgotPasswordForm', 'resetPasswordForm', 'inviteCodeForm', 'applyInviteForm', 'authMessage'];
|
|
3427
3596
|
views.forEach((viewId) => {
|
|
3428
3597
|
const element = this.modal.querySelector(`#${viewId}`);
|
|
3429
3598
|
element?.classList.add('hidden');
|
|
@@ -3434,6 +3603,7 @@ class AuthModal {
|
|
|
3434
3603
|
forgot: 'forgotPasswordForm',
|
|
3435
3604
|
'reset-password': 'resetPasswordForm',
|
|
3436
3605
|
'invite-code': 'inviteCodeForm',
|
|
3606
|
+
'apply-invite': 'applyInviteForm',
|
|
3437
3607
|
message: 'authMessage',
|
|
3438
3608
|
};
|
|
3439
3609
|
const targetView = this.modal.querySelector(`#${viewMap[view]}`);
|
|
@@ -3724,6 +3894,80 @@ class AuthModal {
|
|
|
3724
3894
|
showWarning(title, message) {
|
|
3725
3895
|
Toast.warning(title, message);
|
|
3726
3896
|
}
|
|
3897
|
+
async handleApplyInvite(e) {
|
|
3898
|
+
e.preventDefault();
|
|
3899
|
+
const emailInput = this.modal?.querySelector('#applyInviteEmail');
|
|
3900
|
+
const reasonTextarea = this.modal?.querySelector('#applyInviteReason');
|
|
3901
|
+
const submitBtn = this.modal?.querySelector('#applyInviteButton');
|
|
3902
|
+
const btnText = submitBtn?.querySelector('.btn-text');
|
|
3903
|
+
const btnLoader = submitBtn?.querySelector('.btn-loader');
|
|
3904
|
+
if (!emailInput || !reasonTextarea || !submitBtn)
|
|
3905
|
+
return;
|
|
3906
|
+
const email = emailInput.value.trim();
|
|
3907
|
+
const reason = reasonTextarea.value.trim();
|
|
3908
|
+
// Validate inputs
|
|
3909
|
+
if (!email) {
|
|
3910
|
+
this.showError('Invalid Input', 'Please enter your email address');
|
|
3911
|
+
return;
|
|
3912
|
+
}
|
|
3913
|
+
if (!reason || reason.length < 10) {
|
|
3914
|
+
this.showError('Invalid Input', 'Please provide a reason (at least 10 characters)');
|
|
3915
|
+
return;
|
|
3916
|
+
}
|
|
3917
|
+
if (reason.length > 500) {
|
|
3918
|
+
this.showError('Invalid Input', 'Reason must be less than 500 characters');
|
|
3919
|
+
return;
|
|
3920
|
+
}
|
|
3921
|
+
try {
|
|
3922
|
+
// Show loading state
|
|
3923
|
+
submitBtn.disabled = true;
|
|
3924
|
+
btnText?.classList.add('hidden');
|
|
3925
|
+
btnLoader?.classList.remove('hidden');
|
|
3926
|
+
// Call applyInvite API
|
|
3927
|
+
const result = await this.client.applyInvite({
|
|
3928
|
+
email,
|
|
3929
|
+
reason,
|
|
3930
|
+
});
|
|
3931
|
+
if (result.success && result.data) {
|
|
3932
|
+
// Success
|
|
3933
|
+
Toast.success('Application Submitted', 'Your invitation code application has been submitted successfully. We will review it and send you an email.');
|
|
3934
|
+
// Trigger callback if provided
|
|
3935
|
+
if (this.options.onApplyInviteSuccess) {
|
|
3936
|
+
this.options.onApplyInviteSuccess(result.data.id, result.data.email);
|
|
3937
|
+
}
|
|
3938
|
+
// Clear form
|
|
3939
|
+
emailInput.value = '';
|
|
3940
|
+
reasonTextarea.value = '';
|
|
3941
|
+
const charCount = this.modal?.querySelector('.char-count');
|
|
3942
|
+
if (charCount) {
|
|
3943
|
+
charCount.textContent = '0/500';
|
|
3944
|
+
}
|
|
3945
|
+
// Switch back to login after a delay
|
|
3946
|
+
setTimeout(() => {
|
|
3947
|
+
this.switchView('login');
|
|
3948
|
+
}, 2000);
|
|
3949
|
+
}
|
|
3950
|
+
else {
|
|
3951
|
+
// Handle business errors (e.g., APPLICATION_DUPLICATE)
|
|
3952
|
+
const errorMessage = result.error || 'Failed to submit application';
|
|
3953
|
+
this.showError('Application Failed', errorMessage);
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
catch (error) {
|
|
3957
|
+
// Handle network/server errors
|
|
3958
|
+
const errorMessage = error.response?.data?.error || error.message || 'Failed to submit application';
|
|
3959
|
+
this.showError('Application Failed', errorMessage);
|
|
3960
|
+
if (this.options.onError) {
|
|
3961
|
+
this.options.onError(error);
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
finally {
|
|
3965
|
+
// Reset loading state
|
|
3966
|
+
submitBtn.disabled = false;
|
|
3967
|
+
btnText?.classList.remove('hidden');
|
|
3968
|
+
btnLoader?.classList.add('hidden');
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3727
3971
|
showInfo(title, message) {
|
|
3728
3972
|
Toast.info(title, message);
|
|
3729
3973
|
}
|
|
@@ -3750,8 +3994,7 @@ class AuthModal {
|
|
|
3750
3994
|
async startOAuthFlow(provider) {
|
|
3751
3995
|
try {
|
|
3752
3996
|
// Get the return URL (where user should be redirected after OAuth)
|
|
3753
|
-
|
|
3754
|
-
const return_url = this.options.oauthDesktopURL || this.options.returnUrl || window.location.href;
|
|
3997
|
+
const return_url = this.options.returnUrl || window.location.href;
|
|
3755
3998
|
// Call backend to get OAuth authorization URL
|
|
3756
3999
|
let authorizeUrl;
|
|
3757
4000
|
switch (provider) {
|
|
@@ -3786,7 +4029,6 @@ class AuthModal {
|
|
|
3786
4029
|
*
|
|
3787
4030
|
* In Backend Proxy Mode, the backend redirects to returnUrl with token in query param.
|
|
3788
4031
|
* This static method checks if current URL has a token and processes it.
|
|
3789
|
-
* If oauthDesktopURL is provided, it will redirect to that URL with the token.
|
|
3790
4032
|
*/
|
|
3791
4033
|
static handleOAuthCallback(options) {
|
|
3792
4034
|
const urlParams = new URLSearchParams(window.location.search);
|
|
@@ -3794,19 +4036,6 @@ class AuthModal {
|
|
|
3794
4036
|
if (!token) {
|
|
3795
4037
|
return null; // Not an OAuth callback
|
|
3796
4038
|
}
|
|
3797
|
-
// If oauthDesktopURL is provided, redirect to it with the token
|
|
3798
|
-
if (options.oauthDesktopURL) {
|
|
3799
|
-
// Construct the desktop URL with token parameter
|
|
3800
|
-
const desktopUrl = new URL(options.oauthDesktopURL);
|
|
3801
|
-
desktopUrl.searchParams.set('token', token);
|
|
3802
|
-
// Redirect to desktop app
|
|
3803
|
-
window.location.href = desktopUrl.toString();
|
|
3804
|
-
// Return result (though redirect will happen immediately)
|
|
3805
|
-
return {
|
|
3806
|
-
success: true,
|
|
3807
|
-
token,
|
|
3808
|
-
};
|
|
3809
|
-
}
|
|
3810
4039
|
// Clean up URL (remove token from query string)
|
|
3811
4040
|
const url = new URL(window.location.href);
|
|
3812
4041
|
url.searchParams.delete('token');
|