@vaultix.ai/react 0.1.0 → 0.2.0
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/dist/index.d.mts +35 -4
- package/dist/index.d.ts +35 -4
- package/dist/index.js +481 -202
- package/dist/index.mjs +435 -161
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,10 +21,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
OrganizationSwitcher: () => OrganizationSwitcher,
|
|
24
|
+
RedirectToSignIn: () => RedirectToSignIn,
|
|
25
|
+
RedirectToSignUp: () => RedirectToSignUp,
|
|
24
26
|
SignIn: () => SignIn,
|
|
25
27
|
SignUp: () => SignUp,
|
|
28
|
+
SignedIn: () => SignedIn,
|
|
29
|
+
SignedOut: () => SignedOut,
|
|
26
30
|
UserButton: () => UserButton,
|
|
27
31
|
VaultixProvider: () => VaultixProvider,
|
|
32
|
+
useAuth: () => useAuth,
|
|
28
33
|
useOrganization: () => useOrganization,
|
|
29
34
|
useSession: () => useSession,
|
|
30
35
|
useUser: () => useUser,
|
|
@@ -169,6 +174,7 @@ function VaultixProvider({
|
|
|
169
174
|
}
|
|
170
175
|
|
|
171
176
|
// src/hooks/index.ts
|
|
177
|
+
var import_react2 = require("react");
|
|
172
178
|
function useVaultix() {
|
|
173
179
|
return useVaultixContext();
|
|
174
180
|
}
|
|
@@ -184,10 +190,26 @@ function useOrganization() {
|
|
|
184
190
|
const { organization, isLoaded } = useVaultixContext();
|
|
185
191
|
return { organization, isLoaded };
|
|
186
192
|
}
|
|
193
|
+
function useAuth() {
|
|
194
|
+
const { user, session, isLoaded, isSignedIn, signOut } = useVaultixContext();
|
|
195
|
+
const getToken = (0, import_react2.useCallback)(async () => {
|
|
196
|
+
if (!isSignedIn) return null;
|
|
197
|
+
return null;
|
|
198
|
+
}, [isSignedIn]);
|
|
199
|
+
return {
|
|
200
|
+
isLoaded,
|
|
201
|
+
isSignedIn,
|
|
202
|
+
userId: user?.id ?? null,
|
|
203
|
+
sessionId: session?.id ?? null,
|
|
204
|
+
orgId: session?.orgId ?? null,
|
|
205
|
+
signOut,
|
|
206
|
+
getToken
|
|
207
|
+
};
|
|
208
|
+
}
|
|
187
209
|
|
|
188
210
|
// src/components/SignIn.tsx
|
|
189
211
|
var import_clsx = require("clsx");
|
|
190
|
-
var
|
|
212
|
+
var import_react3 = require("react");
|
|
191
213
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
192
214
|
function toBase64url(buf) {
|
|
193
215
|
return btoa(String.fromCharCode(...new Uint8Array(buf))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
@@ -200,6 +222,18 @@ function resolveApiOrigin2(prop) {
|
|
|
200
222
|
}
|
|
201
223
|
return "";
|
|
202
224
|
}
|
|
225
|
+
function resolveAfterSignInUrl(redirectUrlProp) {
|
|
226
|
+
if (redirectUrlProp) return redirectUrlProp;
|
|
227
|
+
if (typeof document !== "undefined") {
|
|
228
|
+
const el = document.querySelector("[data-vaultix-after-sign-in]");
|
|
229
|
+
const attr = el?.getAttribute("data-vaultix-after-sign-in");
|
|
230
|
+
if (attr) return attr;
|
|
231
|
+
const params = new URLSearchParams(window.location.search);
|
|
232
|
+
const redirectUrl = params.get("redirect_url");
|
|
233
|
+
if (redirectUrl) return redirectUrl;
|
|
234
|
+
}
|
|
235
|
+
return "/";
|
|
236
|
+
}
|
|
203
237
|
function SignIn({
|
|
204
238
|
redirectUrl,
|
|
205
239
|
onSuccess,
|
|
@@ -208,17 +242,32 @@ function SignIn({
|
|
|
208
242
|
className
|
|
209
243
|
}) {
|
|
210
244
|
const apiOrigin = resolveApiOrigin2(apiOriginProp);
|
|
211
|
-
const [step, setStep] = (0,
|
|
212
|
-
const [email, setEmail] = (0,
|
|
213
|
-
const [password, setPassword] = (0,
|
|
214
|
-
const [totp, setTotp] = (0,
|
|
215
|
-
const [
|
|
216
|
-
const [
|
|
217
|
-
const
|
|
245
|
+
const [step, setStep] = (0, import_react3.useState)("email");
|
|
246
|
+
const [email, setEmail] = (0, import_react3.useState)("");
|
|
247
|
+
const [password, setPassword] = (0, import_react3.useState)("");
|
|
248
|
+
const [totp, setTotp] = (0, import_react3.useState)("");
|
|
249
|
+
const [forgotCode, setForgotCode] = (0, import_react3.useState)("");
|
|
250
|
+
const [newPassword, setNewPassword] = (0, import_react3.useState)("");
|
|
251
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
252
|
+
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
253
|
+
const [info, setInfo] = (0, import_react3.useState)(null);
|
|
254
|
+
const challengeIdRef = (0, import_react3.useRef)(null);
|
|
218
255
|
function setErr(msg) {
|
|
219
256
|
setError(msg);
|
|
220
257
|
onError?.(msg);
|
|
221
258
|
}
|
|
259
|
+
function handleSuccess(handshakeToken) {
|
|
260
|
+
onSuccess?.(handshakeToken);
|
|
261
|
+
const target = resolveAfterSignInUrl(redirectUrl);
|
|
262
|
+
const url = new URL(target, window.location.origin);
|
|
263
|
+
url.searchParams.set("__vaultix_handshake", handshakeToken);
|
|
264
|
+
window.location.href = url.toString();
|
|
265
|
+
}
|
|
266
|
+
function handleGoogleSignIn() {
|
|
267
|
+
const target = resolveAfterSignInUrl(redirectUrl);
|
|
268
|
+
const params = new URLSearchParams({ redirect_url: target });
|
|
269
|
+
window.location.href = `${apiOrigin}/v1/auth/oauth/google?${params}`;
|
|
270
|
+
}
|
|
222
271
|
async function handleEmailSubmit(e) {
|
|
223
272
|
e.preventDefault();
|
|
224
273
|
setError(null);
|
|
@@ -263,7 +312,7 @@ function SignIn({
|
|
|
263
312
|
setStep("totp");
|
|
264
313
|
return;
|
|
265
314
|
}
|
|
266
|
-
handleSuccess(data.
|
|
315
|
+
handleSuccess(data.handshake_token);
|
|
267
316
|
} catch {
|
|
268
317
|
setErr("Network error. Please try again.");
|
|
269
318
|
} finally {
|
|
@@ -319,7 +368,7 @@ function SignIn({
|
|
|
319
368
|
setErr(verifyData.error ?? "Passkey verification failed.");
|
|
320
369
|
return;
|
|
321
370
|
}
|
|
322
|
-
handleSuccess(verifyData.
|
|
371
|
+
handleSuccess(verifyData.handshake_token);
|
|
323
372
|
} catch (err) {
|
|
324
373
|
if (err instanceof Error && err.name === "NotAllowedError") {
|
|
325
374
|
setErr("Passkey was cancelled or timed out.");
|
|
@@ -339,28 +388,86 @@ function SignIn({
|
|
|
339
388
|
method: "POST",
|
|
340
389
|
credentials: "include",
|
|
341
390
|
headers: { "Content-Type": "application/json" },
|
|
342
|
-
body: JSON.stringify({
|
|
343
|
-
challenge_id: challengeIdRef.current,
|
|
344
|
-
code: totp
|
|
345
|
-
})
|
|
391
|
+
body: JSON.stringify({ challenge_id: challengeIdRef.current, code: totp })
|
|
346
392
|
});
|
|
347
393
|
const data = await res.json();
|
|
348
394
|
if (!res.ok) {
|
|
349
395
|
setErr(data.error ?? "Invalid code.");
|
|
350
396
|
return;
|
|
351
397
|
}
|
|
352
|
-
handleSuccess(data.
|
|
398
|
+
handleSuccess(data.handshake_token);
|
|
399
|
+
} catch {
|
|
400
|
+
setErr("Network error. Please try again.");
|
|
401
|
+
} finally {
|
|
402
|
+
setLoading(false);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async function handleForgotSubmit(e) {
|
|
406
|
+
e.preventDefault();
|
|
407
|
+
setError(null);
|
|
408
|
+
setLoading(true);
|
|
409
|
+
try {
|
|
410
|
+
await fetch(`${apiOrigin}/v1/auth/forgot-password`, {
|
|
411
|
+
method: "POST",
|
|
412
|
+
credentials: "include",
|
|
413
|
+
headers: { "Content-Type": "application/json" },
|
|
414
|
+
body: JSON.stringify({ email })
|
|
415
|
+
});
|
|
416
|
+
setInfo("Check your email for a reset code.");
|
|
417
|
+
setStep("forgot-verify");
|
|
353
418
|
} catch {
|
|
354
419
|
setErr("Network error. Please try again.");
|
|
355
420
|
} finally {
|
|
356
421
|
setLoading(false);
|
|
357
422
|
}
|
|
358
423
|
}
|
|
359
|
-
function
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
424
|
+
async function handleForgotVerifySubmit(e) {
|
|
425
|
+
e.preventDefault();
|
|
426
|
+
setError(null);
|
|
427
|
+
setInfo(null);
|
|
428
|
+
setStep("forgot-reset");
|
|
363
429
|
}
|
|
430
|
+
async function handleResetPasswordSubmit(e) {
|
|
431
|
+
e.preventDefault();
|
|
432
|
+
setError(null);
|
|
433
|
+
setLoading(true);
|
|
434
|
+
try {
|
|
435
|
+
const res = await fetch(`${apiOrigin}/v1/auth/reset-password`, {
|
|
436
|
+
method: "POST",
|
|
437
|
+
credentials: "include",
|
|
438
|
+
headers: { "Content-Type": "application/json" },
|
|
439
|
+
body: JSON.stringify({ email, code: forgotCode, new_password: newPassword })
|
|
440
|
+
});
|
|
441
|
+
const data = await res.json();
|
|
442
|
+
if (!res.ok) {
|
|
443
|
+
setErr(data.error ?? "Could not reset password.");
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
handleSuccess(data.handshake_token);
|
|
447
|
+
} catch {
|
|
448
|
+
setErr("Network error. Please try again.");
|
|
449
|
+
} finally {
|
|
450
|
+
setLoading(false);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
const title = {
|
|
454
|
+
email: "Sign in",
|
|
455
|
+
password: "Enter password",
|
|
456
|
+
passkey: "Passkey sign-in",
|
|
457
|
+
totp: "Two-factor code",
|
|
458
|
+
forgot: "Forgot password",
|
|
459
|
+
"forgot-verify": "Enter reset code",
|
|
460
|
+
"forgot-reset": "New password"
|
|
461
|
+
};
|
|
462
|
+
const subtitle = {
|
|
463
|
+
email: "Welcome back",
|
|
464
|
+
password: email,
|
|
465
|
+
passkey: email,
|
|
466
|
+
totp: "Enter the 6-digit code from your authenticator app",
|
|
467
|
+
forgot: "We'll send a reset code to your email",
|
|
468
|
+
"forgot-verify": `Code sent to ${email}`,
|
|
469
|
+
"forgot-reset": "Choose a new password"
|
|
470
|
+
};
|
|
364
471
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
365
472
|
"div",
|
|
366
473
|
{
|
|
@@ -373,34 +480,29 @@ function SignIn({
|
|
|
373
480
|
children: [
|
|
374
481
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-8 pt-8 pb-6 text-center", children: [
|
|
375
482
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "inline-flex items-center justify-center w-10 h-10 rounded-xl bg-gradient-to-br from-purple-600 to-blue-600 shadow-lg shadow-purple-500/30 mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LockIcon, {}) }),
|
|
376
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
377
|
-
|
|
378
|
-
step === "password" && "Enter password",
|
|
379
|
-
step === "passkey" && "Passkey sign-in",
|
|
380
|
-
step === "totp" && "Two-factor code"
|
|
381
|
-
] }),
|
|
382
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "text-sm text-[#475569] mt-1", children: [
|
|
383
|
-
step === "email" && "Welcome back",
|
|
384
|
-
step === "password" && email,
|
|
385
|
-
step === "passkey" && email,
|
|
386
|
-
step === "totp" && "Enter the 6-digit code from your authenticator app"
|
|
387
|
-
] })
|
|
483
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-xl font-semibold text-white/90", children: title[step] }),
|
|
484
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-[#475569] mt-1", children: subtitle[step] })
|
|
388
485
|
] }),
|
|
389
486
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
|
|
390
487
|
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-lg bg-red-500/10 border border-red-500/30 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-red-400", children: error }) }),
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
488
|
+
info && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-lg bg-blue-500/10 border border-blue-500/30 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-blue-400", children: info }) }),
|
|
489
|
+
step === "email" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-3", children: [
|
|
490
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GoogleButton, { onClick: handleGoogleSignIn }),
|
|
491
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Divider, {}),
|
|
492
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
|
|
493
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
494
|
+
Input,
|
|
495
|
+
{
|
|
496
|
+
type: "email",
|
|
497
|
+
placeholder: "you@company.com",
|
|
498
|
+
value: email,
|
|
499
|
+
onChange: setEmail,
|
|
500
|
+
autoFocus: true,
|
|
501
|
+
required: true
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
|
|
505
|
+
] })
|
|
404
506
|
] }),
|
|
405
507
|
step === "password" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handlePasswordSubmit, className: "space-y-3", children: [
|
|
406
508
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -415,6 +517,10 @@ function SignIn({
|
|
|
415
517
|
}
|
|
416
518
|
),
|
|
417
519
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Sign in" }),
|
|
520
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
|
|
521
|
+
setStep("forgot");
|
|
522
|
+
setError(null);
|
|
523
|
+
}, children: "Forgot password?" }),
|
|
418
524
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), children: "\u2190 Back" })
|
|
419
525
|
] }),
|
|
420
526
|
step === "passkey" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-3", children: [
|
|
@@ -443,6 +549,58 @@ function SignIn({
|
|
|
443
549
|
),
|
|
444
550
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Verify" }),
|
|
445
551
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), children: "\u2190 Back" })
|
|
552
|
+
] }),
|
|
553
|
+
step === "forgot" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotSubmit, className: "space-y-3", children: [
|
|
554
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
555
|
+
Input,
|
|
556
|
+
{
|
|
557
|
+
type: "email",
|
|
558
|
+
placeholder: "you@company.com",
|
|
559
|
+
value: email,
|
|
560
|
+
onChange: setEmail,
|
|
561
|
+
autoFocus: true,
|
|
562
|
+
required: true
|
|
563
|
+
}
|
|
564
|
+
),
|
|
565
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Send reset code" }),
|
|
566
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
|
|
567
|
+
setStep("password");
|
|
568
|
+
setError(null);
|
|
569
|
+
}, children: "\u2190 Back" })
|
|
570
|
+
] }),
|
|
571
|
+
step === "forgot-verify" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotVerifySubmit, className: "space-y-3", children: [
|
|
572
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
573
|
+
Input,
|
|
574
|
+
{
|
|
575
|
+
type: "text",
|
|
576
|
+
inputMode: "numeric",
|
|
577
|
+
pattern: "[0-9]{6}",
|
|
578
|
+
maxLength: 6,
|
|
579
|
+
placeholder: "000000",
|
|
580
|
+
value: forgotCode,
|
|
581
|
+
onChange: setForgotCode,
|
|
582
|
+
autoFocus: true,
|
|
583
|
+
required: true,
|
|
584
|
+
className: "text-center tracking-[0.4em] text-lg"
|
|
585
|
+
}
|
|
586
|
+
),
|
|
587
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
|
|
588
|
+
] }),
|
|
589
|
+
step === "forgot-reset" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleResetPasswordSubmit, className: "space-y-3", children: [
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
591
|
+
Input,
|
|
592
|
+
{
|
|
593
|
+
type: "password",
|
|
594
|
+
placeholder: "New password",
|
|
595
|
+
value: newPassword,
|
|
596
|
+
onChange: setNewPassword,
|
|
597
|
+
autoFocus: true,
|
|
598
|
+
required: true,
|
|
599
|
+
minLength: 8
|
|
600
|
+
}
|
|
601
|
+
),
|
|
602
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PasswordStrength, { password: newPassword }),
|
|
603
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Reset password" })
|
|
446
604
|
] })
|
|
447
605
|
] })
|
|
448
606
|
]
|
|
@@ -495,28 +653,63 @@ function GhostButton({ children, onClick }) {
|
|
|
495
653
|
}
|
|
496
654
|
);
|
|
497
655
|
}
|
|
498
|
-
function
|
|
656
|
+
function GoogleButton({ onClick }) {
|
|
499
657
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
500
|
-
"
|
|
658
|
+
"button",
|
|
501
659
|
{
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
660
|
+
type: "button",
|
|
661
|
+
onClick,
|
|
662
|
+
className: (0, import_clsx.clsx)(
|
|
663
|
+
"w-full flex items-center justify-center gap-3 px-4 py-2.5 rounded-xl",
|
|
664
|
+
"text-sm font-medium text-white/80",
|
|
665
|
+
"bg-white/5 border border-white/10",
|
|
666
|
+
"hover:bg-white/10 hover:border-white/20",
|
|
667
|
+
"transition-all duration-150"
|
|
668
|
+
),
|
|
506
669
|
children: [
|
|
507
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
508
|
-
|
|
509
|
-
"path",
|
|
510
|
-
{
|
|
511
|
-
className: "opacity-75",
|
|
512
|
-
fill: "currentColor",
|
|
513
|
-
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
514
|
-
}
|
|
515
|
-
)
|
|
670
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GoogleIcon, {}),
|
|
671
|
+
"Continue with Google"
|
|
516
672
|
]
|
|
517
673
|
}
|
|
518
674
|
);
|
|
519
675
|
}
|
|
676
|
+
function Divider() {
|
|
677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
678
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
|
|
680
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
|
|
681
|
+
] });
|
|
682
|
+
}
|
|
683
|
+
function PasswordStrength({ password }) {
|
|
684
|
+
const score = (() => {
|
|
685
|
+
if (password.length === 0) return 0;
|
|
686
|
+
let s = 0;
|
|
687
|
+
if (password.length >= 8) s++;
|
|
688
|
+
if (/[A-Z]/.test(password)) s++;
|
|
689
|
+
if (/[0-9]/.test(password)) s++;
|
|
690
|
+
if (/[^A-Za-z0-9]/.test(password)) s++;
|
|
691
|
+
return s;
|
|
692
|
+
})();
|
|
693
|
+
if (password.length === 0) return null;
|
|
694
|
+
const labels = ["", "Weak", "Fair", "Good", "Strong"];
|
|
695
|
+
const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
|
|
696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-1", children: [
|
|
697
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex gap-1", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
698
|
+
"div",
|
|
699
|
+
{
|
|
700
|
+
className: (0, import_clsx.clsx)("flex-1 h-0.5 rounded-full transition-all duration-300", i <= score ? colors[score] : "bg-white/10")
|
|
701
|
+
},
|
|
702
|
+
i
|
|
703
|
+
)) }),
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-[10px] text-[#475569]", children: labels[score] })
|
|
705
|
+
] });
|
|
706
|
+
}
|
|
707
|
+
function Spinner() {
|
|
708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { className: "animate-spin h-4 w-4 text-white/80", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
709
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
710
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
711
|
+
] });
|
|
712
|
+
}
|
|
520
713
|
function LockIcon() {
|
|
521
714
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
522
715
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
@@ -533,10 +726,18 @@ function FingerprintIcon() {
|
|
|
533
726
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 12v.01" })
|
|
534
727
|
] });
|
|
535
728
|
}
|
|
729
|
+
function GoogleIcon() {
|
|
730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: [
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }),
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }),
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }),
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })
|
|
735
|
+
] });
|
|
736
|
+
}
|
|
536
737
|
|
|
537
738
|
// src/components/SignUp.tsx
|
|
538
739
|
var import_clsx2 = require("clsx");
|
|
539
|
-
var
|
|
740
|
+
var import_react4 = require("react");
|
|
540
741
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
541
742
|
function resolveApiOrigin3(prop) {
|
|
542
743
|
if (prop) return prop;
|
|
@@ -546,6 +747,18 @@ function resolveApiOrigin3(prop) {
|
|
|
546
747
|
}
|
|
547
748
|
return "";
|
|
548
749
|
}
|
|
750
|
+
function resolveAfterSignUpUrl(redirectUrlProp) {
|
|
751
|
+
if (redirectUrlProp) return redirectUrlProp;
|
|
752
|
+
if (typeof document !== "undefined") {
|
|
753
|
+
const el = document.querySelector("[data-vaultix-after-sign-up]");
|
|
754
|
+
const attr = el?.getAttribute("data-vaultix-after-sign-up");
|
|
755
|
+
if (attr) return attr;
|
|
756
|
+
const params = new URLSearchParams(window.location.search);
|
|
757
|
+
const redirectUrl = params.get("redirect_url");
|
|
758
|
+
if (redirectUrl) return redirectUrl;
|
|
759
|
+
}
|
|
760
|
+
return "/";
|
|
761
|
+
}
|
|
549
762
|
function SignUp({
|
|
550
763
|
redirectUrl,
|
|
551
764
|
onSuccess,
|
|
@@ -554,17 +767,29 @@ function SignUp({
|
|
|
554
767
|
className
|
|
555
768
|
}) {
|
|
556
769
|
const apiOrigin = resolveApiOrigin3(apiOriginProp);
|
|
557
|
-
const [step, setStep] = (0,
|
|
558
|
-
const [email, setEmail] = (0,
|
|
559
|
-
const [password, setPassword] = (0,
|
|
560
|
-
const [verificationCode, setVerificationCode] = (0,
|
|
561
|
-
const [error, setError] = (0,
|
|
562
|
-
const [loading, setLoading] = (0,
|
|
563
|
-
const [registrationId, setRegistrationId] = (0,
|
|
770
|
+
const [step, setStep] = (0, import_react4.useState)("email");
|
|
771
|
+
const [email, setEmail] = (0, import_react4.useState)("");
|
|
772
|
+
const [password, setPassword] = (0, import_react4.useState)("");
|
|
773
|
+
const [verificationCode, setVerificationCode] = (0, import_react4.useState)("");
|
|
774
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
775
|
+
const [loading, setLoading] = (0, import_react4.useState)(false);
|
|
776
|
+
const [registrationId, setRegistrationId] = (0, import_react4.useState)(null);
|
|
564
777
|
function setErr(msg) {
|
|
565
778
|
setError(msg);
|
|
566
779
|
onError?.(msg);
|
|
567
780
|
}
|
|
781
|
+
function handleSuccess(handshakeToken) {
|
|
782
|
+
onSuccess?.(handshakeToken);
|
|
783
|
+
const target = resolveAfterSignUpUrl(redirectUrl);
|
|
784
|
+
const url = new URL(target, window.location.origin);
|
|
785
|
+
url.searchParams.set("__vaultix_handshake", handshakeToken);
|
|
786
|
+
window.location.href = url.toString();
|
|
787
|
+
}
|
|
788
|
+
function handleGoogleSignUp() {
|
|
789
|
+
const target = resolveAfterSignUpUrl(redirectUrl);
|
|
790
|
+
const params = new URLSearchParams({ redirect_url: target });
|
|
791
|
+
window.location.href = `${apiOrigin}/v1/auth/oauth/google?${params}`;
|
|
792
|
+
}
|
|
568
793
|
async function handleEmailPassword(e) {
|
|
569
794
|
e.preventDefault();
|
|
570
795
|
setError(null);
|
|
@@ -608,9 +833,7 @@ function SignUp({
|
|
|
608
833
|
setErr(data.error ?? "Invalid code.");
|
|
609
834
|
return;
|
|
610
835
|
}
|
|
611
|
-
|
|
612
|
-
const target = redirectUrl ?? document.querySelector("[data-vaultix-after-sign-up]")?.getAttribute("data-vaultix-after-sign-up") ?? "/";
|
|
613
|
-
if (target) window.location.href = target;
|
|
836
|
+
handleSuccess(data.handshake_token);
|
|
614
837
|
} catch {
|
|
615
838
|
setErr("Network error. Please try again.");
|
|
616
839
|
} finally {
|
|
@@ -645,31 +868,35 @@ function SignUp({
|
|
|
645
868
|
] }),
|
|
646
869
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
|
|
647
870
|
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rounded-lg bg-red-500/10 border border-red-500/30 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-red-400", children: error }) }),
|
|
648
|
-
|
|
649
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
871
|
+
step === "email" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-3", children: [
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleButton2, { onClick: handleGoogleSignUp }),
|
|
873
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Divider2, {}),
|
|
874
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
876
|
+
SignUpInput,
|
|
877
|
+
{
|
|
878
|
+
type: "email",
|
|
879
|
+
placeholder: "you@company.com",
|
|
880
|
+
value: email,
|
|
881
|
+
onChange: setEmail,
|
|
882
|
+
autoFocus: true,
|
|
883
|
+
required: true
|
|
884
|
+
}
|
|
885
|
+
),
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
887
|
+
SignUpInput,
|
|
888
|
+
{
|
|
889
|
+
type: "password",
|
|
890
|
+
placeholder: "Create a password",
|
|
891
|
+
value: password,
|
|
892
|
+
onChange: setPassword,
|
|
893
|
+
required: true,
|
|
894
|
+
minLength: 8
|
|
895
|
+
}
|
|
896
|
+
),
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PasswordStrength2, { password }),
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignUpPrimaryButton, { loading, children: "Create account" })
|
|
899
|
+
] })
|
|
673
900
|
] }),
|
|
674
901
|
step === "verify" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleVerification, className: "space-y-3", children: [
|
|
675
902
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -739,7 +966,34 @@ function SignUpPrimaryButton({
|
|
|
739
966
|
}
|
|
740
967
|
);
|
|
741
968
|
}
|
|
742
|
-
function
|
|
969
|
+
function GoogleButton2({ onClick }) {
|
|
970
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
971
|
+
"button",
|
|
972
|
+
{
|
|
973
|
+
type: "button",
|
|
974
|
+
onClick,
|
|
975
|
+
className: (0, import_clsx2.clsx)(
|
|
976
|
+
"w-full flex items-center justify-center gap-3 px-4 py-2.5 rounded-xl",
|
|
977
|
+
"text-sm font-medium text-white/80",
|
|
978
|
+
"bg-white/5 border border-white/10",
|
|
979
|
+
"hover:bg-white/10 hover:border-white/20",
|
|
980
|
+
"transition-all duration-150"
|
|
981
|
+
),
|
|
982
|
+
children: [
|
|
983
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleIcon2, {}),
|
|
984
|
+
"Continue with Google"
|
|
985
|
+
]
|
|
986
|
+
}
|
|
987
|
+
);
|
|
988
|
+
}
|
|
989
|
+
function Divider2() {
|
|
990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-white/8" })
|
|
994
|
+
] });
|
|
995
|
+
}
|
|
996
|
+
function PasswordStrength2({ password }) {
|
|
743
997
|
const score = (() => {
|
|
744
998
|
if (password.length === 0) return 0;
|
|
745
999
|
let s = 0;
|
|
@@ -751,13 +1005,7 @@ function PasswordStrength({ password }) {
|
|
|
751
1005
|
})();
|
|
752
1006
|
if (password.length === 0) return null;
|
|
753
1007
|
const labels = ["", "Weak", "Fair", "Good", "Strong"];
|
|
754
|
-
const colors = [
|
|
755
|
-
"",
|
|
756
|
-
"bg-red-500",
|
|
757
|
-
"bg-amber-400",
|
|
758
|
-
"bg-blue-400",
|
|
759
|
-
"bg-emerald-400"
|
|
760
|
-
];
|
|
1008
|
+
const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
|
|
761
1009
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-1", children: [
|
|
762
1010
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex gap-1", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
763
1011
|
"div",
|
|
@@ -773,45 +1021,71 @@ function PasswordStrength({ password }) {
|
|
|
773
1021
|
] });
|
|
774
1022
|
}
|
|
775
1023
|
function Spinner2() {
|
|
776
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
777
|
-
"
|
|
778
|
-
{
|
|
779
|
-
|
|
780
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
781
|
-
fill: "none",
|
|
782
|
-
viewBox: "0 0 24 24",
|
|
783
|
-
children: [
|
|
784
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
785
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
786
|
-
"path",
|
|
787
|
-
{
|
|
788
|
-
className: "opacity-75",
|
|
789
|
-
fill: "currentColor",
|
|
790
|
-
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
791
|
-
}
|
|
792
|
-
)
|
|
793
|
-
]
|
|
794
|
-
}
|
|
795
|
-
);
|
|
1024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { className: "animate-spin h-4 w-4 text-white/80", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1026
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
1027
|
+
] });
|
|
796
1028
|
}
|
|
797
1029
|
function SparkleIcon() {
|
|
798
1030
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) });
|
|
799
1031
|
}
|
|
1032
|
+
function GoogleIcon2() {
|
|
1033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: [
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }),
|
|
1035
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }),
|
|
1036
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }),
|
|
1037
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })
|
|
1038
|
+
] });
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// src/components/SignedIn.tsx
|
|
1042
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1043
|
+
function SignedIn({ children }) {
|
|
1044
|
+
const { isLoaded, isSignedIn } = useVaultixContext();
|
|
1045
|
+
if (!isLoaded || !isSignedIn) return null;
|
|
1046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children });
|
|
1047
|
+
}
|
|
1048
|
+
function SignedOut({ children }) {
|
|
1049
|
+
const { isLoaded, isSignedIn } = useVaultixContext();
|
|
1050
|
+
if (!isLoaded || isSignedIn) return null;
|
|
1051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children });
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// src/components/RedirectComponents.tsx
|
|
1055
|
+
var import_react5 = require("react");
|
|
1056
|
+
function RedirectToSignIn({ redirectUrl = "/sign-in" }) {
|
|
1057
|
+
const { isLoaded, isSignedIn } = useVaultixContext();
|
|
1058
|
+
(0, import_react5.useEffect)(() => {
|
|
1059
|
+
if (isLoaded && !isSignedIn) {
|
|
1060
|
+
window.location.href = redirectUrl;
|
|
1061
|
+
}
|
|
1062
|
+
}, [isLoaded, isSignedIn, redirectUrl]);
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
1065
|
+
function RedirectToSignUp({ redirectUrl = "/sign-up" }) {
|
|
1066
|
+
const { isLoaded, isSignedIn } = useVaultixContext();
|
|
1067
|
+
(0, import_react5.useEffect)(() => {
|
|
1068
|
+
if (isLoaded && !isSignedIn) {
|
|
1069
|
+
window.location.href = redirectUrl;
|
|
1070
|
+
}
|
|
1071
|
+
}, [isLoaded, isSignedIn, redirectUrl]);
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
800
1074
|
|
|
801
1075
|
// src/components/UserButton.tsx
|
|
802
1076
|
var import_clsx3 = require("clsx");
|
|
803
|
-
var
|
|
804
|
-
var
|
|
1077
|
+
var import_react6 = require("react");
|
|
1078
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
805
1079
|
function UserButton({
|
|
806
1080
|
showName = false,
|
|
807
1081
|
afterSignOutUrl,
|
|
808
1082
|
className
|
|
809
1083
|
}) {
|
|
810
1084
|
const { user, session, isLoaded, isSignedIn, signOut } = useVaultixContext();
|
|
811
|
-
const [open, setOpen] = (0,
|
|
812
|
-
const [signingOut, setSigningOut] = (0,
|
|
813
|
-
const containerRef = (0,
|
|
814
|
-
(0,
|
|
1085
|
+
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
1086
|
+
const [signingOut, setSigningOut] = (0, import_react6.useState)(false);
|
|
1087
|
+
const containerRef = (0, import_react6.useRef)(null);
|
|
1088
|
+
(0, import_react6.useEffect)(() => {
|
|
815
1089
|
function onPointerDown(e) {
|
|
816
1090
|
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
817
1091
|
setOpen(false);
|
|
@@ -820,7 +1094,7 @@ function UserButton({
|
|
|
820
1094
|
document.addEventListener("pointerdown", onPointerDown);
|
|
821
1095
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
822
1096
|
}, []);
|
|
823
|
-
if (!isLoaded) return /* @__PURE__ */ (0,
|
|
1097
|
+
if (!isLoaded) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AvatarSkeleton, {});
|
|
824
1098
|
if (!isSignedIn || !user) return null;
|
|
825
1099
|
const initials = [user.firstName, user.lastName].filter(Boolean).map((s) => s.charAt(0)).join("").toUpperCase() || user.email.charAt(0).toUpperCase();
|
|
826
1100
|
async function handleSignOut() {
|
|
@@ -828,19 +1102,19 @@ function UserButton({
|
|
|
828
1102
|
await signOut();
|
|
829
1103
|
if (afterSignOutUrl) window.location.href = afterSignOutUrl;
|
|
830
1104
|
}
|
|
831
|
-
return /* @__PURE__ */ (0,
|
|
832
|
-
/* @__PURE__ */ (0,
|
|
1105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: containerRef, className: (0, import_clsx3.clsx)("relative", className), children: [
|
|
1106
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
833
1107
|
"button",
|
|
834
1108
|
{
|
|
835
1109
|
onClick: () => setOpen((o) => !o),
|
|
836
1110
|
className: "flex items-center gap-2 rounded-xl p-1 hover:bg-white/8 transition-colors",
|
|
837
1111
|
children: [
|
|
838
|
-
/* @__PURE__ */ (0,
|
|
839
|
-
showName && /* @__PURE__ */ (0,
|
|
1112
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Avatar, { initials, imageUrl: user.imageUrl }),
|
|
1113
|
+
showName && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm font-medium text-white/90 pr-1", children: user.firstName ?? user.email })
|
|
840
1114
|
]
|
|
841
1115
|
}
|
|
842
1116
|
),
|
|
843
|
-
open && /* @__PURE__ */ (0,
|
|
1117
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
844
1118
|
"div",
|
|
845
1119
|
{
|
|
846
1120
|
className: (0, import_clsx3.clsx)(
|
|
@@ -849,40 +1123,40 @@ function UserButton({
|
|
|
849
1123
|
),
|
|
850
1124
|
style: { background: "rgba(22,27,45,0.96)" },
|
|
851
1125
|
children: [
|
|
852
|
-
/* @__PURE__ */ (0,
|
|
853
|
-
/* @__PURE__ */ (0,
|
|
854
|
-
/* @__PURE__ */ (0,
|
|
855
|
-
(user.firstName || user.lastName) && /* @__PURE__ */ (0,
|
|
856
|
-
/* @__PURE__ */ (0,
|
|
1126
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-white/8", children: [
|
|
1127
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Avatar, { initials, imageUrl: user.imageUrl, size: "lg" }),
|
|
1128
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
1129
|
+
(user.firstName || user.lastName) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-semibold text-white/90 truncate", children: [user.firstName, user.lastName].filter(Boolean).join(" ") }),
|
|
1130
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-xs text-[#475569] truncate", children: user.email })
|
|
857
1131
|
] })
|
|
858
1132
|
] }),
|
|
859
|
-
session && /* @__PURE__ */ (0,
|
|
860
|
-
/* @__PURE__ */ (0,
|
|
861
|
-
/* @__PURE__ */ (0,
|
|
1133
|
+
session && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "px-4 py-2 border-b border-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Risk level" }),
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RiskBadge, { level: session.riskLevel })
|
|
862
1136
|
] }) }),
|
|
863
|
-
/* @__PURE__ */ (0,
|
|
864
|
-
/* @__PURE__ */ (0,
|
|
1137
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "p-2", children: [
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
865
1139
|
DropdownItem,
|
|
866
1140
|
{
|
|
867
1141
|
label: "Manage account",
|
|
868
|
-
icon: /* @__PURE__ */ (0,
|
|
1142
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UserIcon, {}),
|
|
869
1143
|
onClick: () => setOpen(false)
|
|
870
1144
|
}
|
|
871
1145
|
),
|
|
872
|
-
/* @__PURE__ */ (0,
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
873
1147
|
DropdownItem,
|
|
874
1148
|
{
|
|
875
1149
|
label: "Security settings",
|
|
876
|
-
icon: /* @__PURE__ */ (0,
|
|
1150
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ShieldIcon, {}),
|
|
877
1151
|
onClick: () => setOpen(false)
|
|
878
1152
|
}
|
|
879
1153
|
),
|
|
880
|
-
/* @__PURE__ */ (0,
|
|
881
|
-
/* @__PURE__ */ (0,
|
|
1154
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-px bg-white/8 my-1" }),
|
|
1155
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
882
1156
|
DropdownItem,
|
|
883
1157
|
{
|
|
884
1158
|
label: signingOut ? "Signing out\u2026" : "Sign out",
|
|
885
|
-
icon: /* @__PURE__ */ (0,
|
|
1159
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SignOutIcon, {}),
|
|
886
1160
|
onClick: handleSignOut,
|
|
887
1161
|
destructive: true
|
|
888
1162
|
}
|
|
@@ -898,7 +1172,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
|
|
|
898
1172
|
if (imageUrl) {
|
|
899
1173
|
return (
|
|
900
1174
|
// eslint-disable-next-line @next/next/no-img-element
|
|
901
|
-
/* @__PURE__ */ (0,
|
|
1175
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
902
1176
|
"img",
|
|
903
1177
|
{
|
|
904
1178
|
src: imageUrl,
|
|
@@ -908,7 +1182,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
|
|
|
908
1182
|
)
|
|
909
1183
|
);
|
|
910
1184
|
}
|
|
911
|
-
return /* @__PURE__ */ (0,
|
|
1185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
912
1186
|
"div",
|
|
913
1187
|
{
|
|
914
1188
|
className: (0, import_clsx3.clsx)(
|
|
@@ -921,7 +1195,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
|
|
|
921
1195
|
);
|
|
922
1196
|
}
|
|
923
1197
|
function AvatarSkeleton() {
|
|
924
|
-
return /* @__PURE__ */ (0,
|
|
1198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-8 h-8 rounded-full bg-white/5 animate-pulse" });
|
|
925
1199
|
}
|
|
926
1200
|
function RiskBadge({ level }) {
|
|
927
1201
|
const styles = {
|
|
@@ -930,7 +1204,7 @@ function RiskBadge({ level }) {
|
|
|
930
1204
|
high: "bg-orange-500/15 text-orange-400 border-orange-500/30",
|
|
931
1205
|
critical: "bg-red-500/15 text-red-400 border-red-500/30"
|
|
932
1206
|
};
|
|
933
|
-
return /* @__PURE__ */ (0,
|
|
1207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
934
1208
|
"span",
|
|
935
1209
|
{
|
|
936
1210
|
className: (0, import_clsx3.clsx)(
|
|
@@ -942,7 +1216,7 @@ function RiskBadge({ level }) {
|
|
|
942
1216
|
);
|
|
943
1217
|
}
|
|
944
1218
|
function DropdownItem({ label, icon, onClick, destructive }) {
|
|
945
|
-
return /* @__PURE__ */ (0,
|
|
1219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
946
1220
|
"button",
|
|
947
1221
|
{
|
|
948
1222
|
onClick,
|
|
@@ -951,33 +1225,33 @@ function DropdownItem({ label, icon, onClick, destructive }) {
|
|
|
951
1225
|
destructive ? "text-red-400 hover:bg-red-500/10" : "text-white/70 hover:text-white hover:bg-white/8"
|
|
952
1226
|
),
|
|
953
1227
|
children: [
|
|
954
|
-
/* @__PURE__ */ (0,
|
|
1228
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "opacity-70", children: icon }),
|
|
955
1229
|
label
|
|
956
1230
|
]
|
|
957
1231
|
}
|
|
958
1232
|
);
|
|
959
1233
|
}
|
|
960
1234
|
function UserIcon() {
|
|
961
|
-
return /* @__PURE__ */ (0,
|
|
962
|
-
/* @__PURE__ */ (0,
|
|
963
|
-
/* @__PURE__ */ (0,
|
|
1235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1236
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }),
|
|
1237
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "7", r: "4" })
|
|
964
1238
|
] });
|
|
965
1239
|
}
|
|
966
1240
|
function ShieldIcon() {
|
|
967
|
-
return /* @__PURE__ */ (0,
|
|
1241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) });
|
|
968
1242
|
}
|
|
969
1243
|
function SignOutIcon() {
|
|
970
|
-
return /* @__PURE__ */ (0,
|
|
971
|
-
/* @__PURE__ */ (0,
|
|
972
|
-
/* @__PURE__ */ (0,
|
|
973
|
-
/* @__PURE__ */ (0,
|
|
1244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1245
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("polyline", { points: "16 17 21 12 16 7" }),
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
|
|
974
1248
|
] });
|
|
975
1249
|
}
|
|
976
1250
|
|
|
977
1251
|
// src/components/OrganizationSwitcher.tsx
|
|
978
1252
|
var import_clsx4 = require("clsx");
|
|
979
|
-
var
|
|
980
|
-
var
|
|
1253
|
+
var import_react7 = require("react");
|
|
1254
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
981
1255
|
function resolveApiOrigin4() {
|
|
982
1256
|
if (typeof document !== "undefined") {
|
|
983
1257
|
const el = document.querySelector("[data-vaultix-api]");
|
|
@@ -990,11 +1264,11 @@ function OrganizationSwitcher({
|
|
|
990
1264
|
className
|
|
991
1265
|
}) {
|
|
992
1266
|
const { organization, isLoaded, isSignedIn } = useVaultixContext();
|
|
993
|
-
const [open, setOpen] = (0,
|
|
994
|
-
const [orgs, setOrgs] = (0,
|
|
995
|
-
const [switching, setSwitching] = (0,
|
|
996
|
-
const containerRef = (0,
|
|
997
|
-
(0,
|
|
1267
|
+
const [open, setOpen] = (0, import_react7.useState)(false);
|
|
1268
|
+
const [orgs, setOrgs] = (0, import_react7.useState)([]);
|
|
1269
|
+
const [switching, setSwitching] = (0, import_react7.useState)(null);
|
|
1270
|
+
const containerRef = (0, import_react7.useRef)(null);
|
|
1271
|
+
(0, import_react7.useEffect)(() => {
|
|
998
1272
|
function onPointerDown(e) {
|
|
999
1273
|
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
1000
1274
|
setOpen(false);
|
|
@@ -1003,7 +1277,7 @@ function OrganizationSwitcher({
|
|
|
1003
1277
|
document.addEventListener("pointerdown", onPointerDown);
|
|
1004
1278
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
1005
1279
|
}, []);
|
|
1006
|
-
(0,
|
|
1280
|
+
(0, import_react7.useEffect)(() => {
|
|
1007
1281
|
if (!open) return;
|
|
1008
1282
|
const api = resolveApiOrigin4();
|
|
1009
1283
|
fetch(`${api}/v1/me/organizations`, { credentials: "include" }).then((r) => r.json()).then(
|
|
@@ -1037,8 +1311,8 @@ function OrganizationSwitcher({
|
|
|
1037
1311
|
}
|
|
1038
1312
|
const displayName = organization?.name ?? "Personal";
|
|
1039
1313
|
const initials = displayName.split(/\s+/).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
|
|
1040
|
-
return /* @__PURE__ */ (0,
|
|
1041
|
-
/* @__PURE__ */ (0,
|
|
1314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: containerRef, className: (0, import_clsx4.clsx)("relative", className), children: [
|
|
1315
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1042
1316
|
"button",
|
|
1043
1317
|
{
|
|
1044
1318
|
onClick: () => setOpen((o) => !o),
|
|
@@ -1048,16 +1322,16 @@ function OrganizationSwitcher({
|
|
|
1048
1322
|
"transition-all duration-150"
|
|
1049
1323
|
),
|
|
1050
1324
|
children: [
|
|
1051
|
-
/* @__PURE__ */ (0,
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1054
|
-
organization && /* @__PURE__ */ (0,
|
|
1325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(OrgAvatar, { initials }),
|
|
1326
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "text-left min-w-0", children: [
|
|
1327
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-sm font-semibold text-white/90 truncate max-w-[120px]", children: displayName }),
|
|
1328
|
+
organization && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[10px] text-[#475569] capitalize", children: organization.role })
|
|
1055
1329
|
] }),
|
|
1056
|
-
/* @__PURE__ */ (0,
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChevronIcon, {})
|
|
1057
1331
|
]
|
|
1058
1332
|
}
|
|
1059
1333
|
),
|
|
1060
|
-
open && /* @__PURE__ */ (0,
|
|
1334
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1061
1335
|
"div",
|
|
1062
1336
|
{
|
|
1063
1337
|
className: (0, import_clsx4.clsx)(
|
|
@@ -1066,13 +1340,13 @@ function OrganizationSwitcher({
|
|
|
1066
1340
|
),
|
|
1067
1341
|
style: { background: "rgba(22,27,45,0.96)" },
|
|
1068
1342
|
children: [
|
|
1069
|
-
/* @__PURE__ */ (0,
|
|
1070
|
-
/* @__PURE__ */ (0,
|
|
1071
|
-
orgs.length === 0 && /* @__PURE__ */ (0,
|
|
1343
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "px-4 py-3 border-b border-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Switch organization" }) }),
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "p-2 max-h-56 overflow-y-auto", children: [
|
|
1345
|
+
orgs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-[#475569] text-center py-4", children: "Loading\u2026" }),
|
|
1072
1346
|
orgs.map((org) => {
|
|
1073
1347
|
const isActive = org.id === organization?.id;
|
|
1074
1348
|
const orgInitials = org.name.split(/\s+/).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
|
|
1075
|
-
return /* @__PURE__ */ (0,
|
|
1349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1076
1350
|
"button",
|
|
1077
1351
|
{
|
|
1078
1352
|
onClick: () => !isActive && switchOrg(org.id),
|
|
@@ -1082,9 +1356,9 @@ function OrganizationSwitcher({
|
|
|
1082
1356
|
isActive ? "bg-purple-500/10 cursor-default" : "hover:bg-white/8 cursor-pointer"
|
|
1083
1357
|
),
|
|
1084
1358
|
children: [
|
|
1085
|
-
/* @__PURE__ */ (0,
|
|
1086
|
-
/* @__PURE__ */ (0,
|
|
1087
|
-
/* @__PURE__ */ (0,
|
|
1359
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(OrgAvatar, { initials: orgInitials, active: isActive }),
|
|
1360
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
1361
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1088
1362
|
"p",
|
|
1089
1363
|
{
|
|
1090
1364
|
className: (0, import_clsx4.clsx)(
|
|
@@ -1094,17 +1368,17 @@ function OrganizationSwitcher({
|
|
|
1094
1368
|
children: org.name
|
|
1095
1369
|
}
|
|
1096
1370
|
),
|
|
1097
|
-
/* @__PURE__ */ (0,
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[10px] text-[#475569] capitalize", children: org.role })
|
|
1098
1372
|
] }),
|
|
1099
|
-
isActive && /* @__PURE__ */ (0,
|
|
1100
|
-
switching === org.id && /* @__PURE__ */ (0,
|
|
1373
|
+
isActive && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-purple-400 shrink-0" }),
|
|
1374
|
+
switching === org.id && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MiniSpinner, {})
|
|
1101
1375
|
]
|
|
1102
1376
|
},
|
|
1103
1377
|
org.id
|
|
1104
1378
|
);
|
|
1105
1379
|
})
|
|
1106
1380
|
] }),
|
|
1107
|
-
/* @__PURE__ */ (0,
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "p-2 border-t border-white/8", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1108
1382
|
"button",
|
|
1109
1383
|
{
|
|
1110
1384
|
onClick: () => {
|
|
@@ -1112,7 +1386,7 @@ function OrganizationSwitcher({
|
|
|
1112
1386
|
},
|
|
1113
1387
|
className: "w-full flex items-center gap-2 px-3 py-2 rounded-xl text-sm text-[#475569] hover:text-white hover:bg-white/8 transition-colors",
|
|
1114
1388
|
children: [
|
|
1115
|
-
/* @__PURE__ */ (0,
|
|
1389
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PlusIcon, {}),
|
|
1116
1390
|
"Create organization"
|
|
1117
1391
|
]
|
|
1118
1392
|
}
|
|
@@ -1126,7 +1400,7 @@ function OrgAvatar({
|
|
|
1126
1400
|
initials,
|
|
1127
1401
|
active = false
|
|
1128
1402
|
}) {
|
|
1129
|
-
return /* @__PURE__ */ (0,
|
|
1403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1130
1404
|
"div",
|
|
1131
1405
|
{
|
|
1132
1406
|
className: (0, import_clsx4.clsx)(
|
|
@@ -1138,7 +1412,7 @@ function OrgAvatar({
|
|
|
1138
1412
|
);
|
|
1139
1413
|
}
|
|
1140
1414
|
function ChevronIcon() {
|
|
1141
|
-
return /* @__PURE__ */ (0,
|
|
1415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1142
1416
|
"svg",
|
|
1143
1417
|
{
|
|
1144
1418
|
width: "12",
|
|
@@ -1150,29 +1424,34 @@ function ChevronIcon() {
|
|
|
1150
1424
|
strokeLinecap: "round",
|
|
1151
1425
|
strokeLinejoin: "round",
|
|
1152
1426
|
className: "text-[#475569] shrink-0",
|
|
1153
|
-
children: /* @__PURE__ */ (0,
|
|
1427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "6 9 12 15 18 9" })
|
|
1154
1428
|
}
|
|
1155
1429
|
);
|
|
1156
1430
|
}
|
|
1157
1431
|
function PlusIcon() {
|
|
1158
|
-
return /* @__PURE__ */ (0,
|
|
1159
|
-
/* @__PURE__ */ (0,
|
|
1160
|
-
/* @__PURE__ */ (0,
|
|
1432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
1161
1435
|
] });
|
|
1162
1436
|
}
|
|
1163
1437
|
function MiniSpinner() {
|
|
1164
|
-
return /* @__PURE__ */ (0,
|
|
1165
|
-
/* @__PURE__ */ (0,
|
|
1166
|
-
/* @__PURE__ */ (0,
|
|
1438
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { className: "animate-spin h-3 w-3 text-[#475569]", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
1167
1441
|
] });
|
|
1168
1442
|
}
|
|
1169
1443
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1170
1444
|
0 && (module.exports = {
|
|
1171
1445
|
OrganizationSwitcher,
|
|
1446
|
+
RedirectToSignIn,
|
|
1447
|
+
RedirectToSignUp,
|
|
1172
1448
|
SignIn,
|
|
1173
1449
|
SignUp,
|
|
1450
|
+
SignedIn,
|
|
1451
|
+
SignedOut,
|
|
1174
1452
|
UserButton,
|
|
1175
1453
|
VaultixProvider,
|
|
1454
|
+
useAuth,
|
|
1176
1455
|
useOrganization,
|
|
1177
1456
|
useSession,
|
|
1178
1457
|
useUser,
|