@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.mjs CHANGED
@@ -142,6 +142,7 @@ function VaultixProvider({
142
142
  }
143
143
 
144
144
  // src/hooks/index.ts
145
+ import { useCallback as useCallback2 } from "react";
145
146
  function useVaultix() {
146
147
  return useVaultixContext();
147
148
  }
@@ -157,6 +158,22 @@ function useOrganization() {
157
158
  const { organization, isLoaded } = useVaultixContext();
158
159
  return { organization, isLoaded };
159
160
  }
161
+ function useAuth() {
162
+ const { user, session, isLoaded, isSignedIn, signOut } = useVaultixContext();
163
+ const getToken = useCallback2(async () => {
164
+ if (!isSignedIn) return null;
165
+ return null;
166
+ }, [isSignedIn]);
167
+ return {
168
+ isLoaded,
169
+ isSignedIn,
170
+ userId: user?.id ?? null,
171
+ sessionId: session?.id ?? null,
172
+ orgId: session?.orgId ?? null,
173
+ signOut,
174
+ getToken
175
+ };
176
+ }
160
177
 
161
178
  // src/components/SignIn.tsx
162
179
  import { clsx } from "clsx";
@@ -173,6 +190,18 @@ function resolveApiOrigin2(prop) {
173
190
  }
174
191
  return "";
175
192
  }
193
+ function resolveAfterSignInUrl(redirectUrlProp) {
194
+ if (redirectUrlProp) return redirectUrlProp;
195
+ if (typeof document !== "undefined") {
196
+ const el = document.querySelector("[data-vaultix-after-sign-in]");
197
+ const attr = el?.getAttribute("data-vaultix-after-sign-in");
198
+ if (attr) return attr;
199
+ const params = new URLSearchParams(window.location.search);
200
+ const redirectUrl = params.get("redirect_url");
201
+ if (redirectUrl) return redirectUrl;
202
+ }
203
+ return "/";
204
+ }
176
205
  function SignIn({
177
206
  redirectUrl,
178
207
  onSuccess,
@@ -185,13 +214,28 @@ function SignIn({
185
214
  const [email, setEmail] = useState2("");
186
215
  const [password, setPassword] = useState2("");
187
216
  const [totp, setTotp] = useState2("");
217
+ const [forgotCode, setForgotCode] = useState2("");
218
+ const [newPassword, setNewPassword] = useState2("");
188
219
  const [error, setError] = useState2(null);
189
220
  const [loading, setLoading] = useState2(false);
221
+ const [info, setInfo] = useState2(null);
190
222
  const challengeIdRef = useRef2(null);
191
223
  function setErr(msg) {
192
224
  setError(msg);
193
225
  onError?.(msg);
194
226
  }
227
+ function handleSuccess(handshakeToken) {
228
+ onSuccess?.(handshakeToken);
229
+ const target = resolveAfterSignInUrl(redirectUrl);
230
+ const url = new URL(target, window.location.origin);
231
+ url.searchParams.set("__vaultix_handshake", handshakeToken);
232
+ window.location.href = url.toString();
233
+ }
234
+ function handleGoogleSignIn() {
235
+ const target = resolveAfterSignInUrl(redirectUrl);
236
+ const params = new URLSearchParams({ redirect_url: target });
237
+ window.location.href = `${apiOrigin}/v1/auth/oauth/google?${params}`;
238
+ }
195
239
  async function handleEmailSubmit(e) {
196
240
  e.preventDefault();
197
241
  setError(null);
@@ -236,7 +280,7 @@ function SignIn({
236
280
  setStep("totp");
237
281
  return;
238
282
  }
239
- handleSuccess(data.session_id);
283
+ handleSuccess(data.handshake_token);
240
284
  } catch {
241
285
  setErr("Network error. Please try again.");
242
286
  } finally {
@@ -292,7 +336,7 @@ function SignIn({
292
336
  setErr(verifyData.error ?? "Passkey verification failed.");
293
337
  return;
294
338
  }
295
- handleSuccess(verifyData.session_id);
339
+ handleSuccess(verifyData.handshake_token);
296
340
  } catch (err) {
297
341
  if (err instanceof Error && err.name === "NotAllowedError") {
298
342
  setErr("Passkey was cancelled or timed out.");
@@ -312,28 +356,86 @@ function SignIn({
312
356
  method: "POST",
313
357
  credentials: "include",
314
358
  headers: { "Content-Type": "application/json" },
315
- body: JSON.stringify({
316
- challenge_id: challengeIdRef.current,
317
- code: totp
318
- })
359
+ body: JSON.stringify({ challenge_id: challengeIdRef.current, code: totp })
319
360
  });
320
361
  const data = await res.json();
321
362
  if (!res.ok) {
322
363
  setErr(data.error ?? "Invalid code.");
323
364
  return;
324
365
  }
325
- handleSuccess(data.session_id);
366
+ handleSuccess(data.handshake_token);
367
+ } catch {
368
+ setErr("Network error. Please try again.");
369
+ } finally {
370
+ setLoading(false);
371
+ }
372
+ }
373
+ async function handleForgotSubmit(e) {
374
+ e.preventDefault();
375
+ setError(null);
376
+ setLoading(true);
377
+ try {
378
+ await fetch(`${apiOrigin}/v1/auth/forgot-password`, {
379
+ method: "POST",
380
+ credentials: "include",
381
+ headers: { "Content-Type": "application/json" },
382
+ body: JSON.stringify({ email })
383
+ });
384
+ setInfo("Check your email for a reset code.");
385
+ setStep("forgot-verify");
326
386
  } catch {
327
387
  setErr("Network error. Please try again.");
328
388
  } finally {
329
389
  setLoading(false);
330
390
  }
331
391
  }
332
- function handleSuccess(sessionId) {
333
- onSuccess?.(sessionId);
334
- const target = redirectUrl ?? document.querySelector("[data-vaultix-after-sign-in]")?.getAttribute("data-vaultix-after-sign-in") ?? "/";
335
- if (target) window.location.href = target;
392
+ async function handleForgotVerifySubmit(e) {
393
+ e.preventDefault();
394
+ setError(null);
395
+ setInfo(null);
396
+ setStep("forgot-reset");
336
397
  }
398
+ async function handleResetPasswordSubmit(e) {
399
+ e.preventDefault();
400
+ setError(null);
401
+ setLoading(true);
402
+ try {
403
+ const res = await fetch(`${apiOrigin}/v1/auth/reset-password`, {
404
+ method: "POST",
405
+ credentials: "include",
406
+ headers: { "Content-Type": "application/json" },
407
+ body: JSON.stringify({ email, code: forgotCode, new_password: newPassword })
408
+ });
409
+ const data = await res.json();
410
+ if (!res.ok) {
411
+ setErr(data.error ?? "Could not reset password.");
412
+ return;
413
+ }
414
+ handleSuccess(data.handshake_token);
415
+ } catch {
416
+ setErr("Network error. Please try again.");
417
+ } finally {
418
+ setLoading(false);
419
+ }
420
+ }
421
+ const title = {
422
+ email: "Sign in",
423
+ password: "Enter password",
424
+ passkey: "Passkey sign-in",
425
+ totp: "Two-factor code",
426
+ forgot: "Forgot password",
427
+ "forgot-verify": "Enter reset code",
428
+ "forgot-reset": "New password"
429
+ };
430
+ const subtitle = {
431
+ email: "Welcome back",
432
+ password: email,
433
+ passkey: email,
434
+ totp: "Enter the 6-digit code from your authenticator app",
435
+ forgot: "We'll send a reset code to your email",
436
+ "forgot-verify": `Code sent to ${email}`,
437
+ "forgot-reset": "Choose a new password"
438
+ };
337
439
  return /* @__PURE__ */ jsxs(
338
440
  "div",
339
441
  {
@@ -346,34 +448,29 @@ function SignIn({
346
448
  children: [
347
449
  /* @__PURE__ */ jsxs("div", { className: "px-8 pt-8 pb-6 text-center", children: [
348
450
  /* @__PURE__ */ jsx2("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__ */ jsx2(LockIcon, {}) }),
349
- /* @__PURE__ */ jsxs("h1", { className: "text-xl font-semibold text-white/90", children: [
350
- step === "email" && "Sign in",
351
- step === "password" && "Enter password",
352
- step === "passkey" && "Passkey sign-in",
353
- step === "totp" && "Two-factor code"
354
- ] }),
355
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-[#475569] mt-1", children: [
356
- step === "email" && "Welcome back",
357
- step === "password" && email,
358
- step === "passkey" && email,
359
- step === "totp" && "Enter the 6-digit code from your authenticator app"
360
- ] })
451
+ /* @__PURE__ */ jsx2("h1", { className: "text-xl font-semibold text-white/90", children: title[step] }),
452
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-[#475569] mt-1", children: subtitle[step] })
361
453
  ] }),
362
454
  /* @__PURE__ */ jsxs("div", { className: "px-8 pb-8 space-y-4", children: [
363
455
  error && /* @__PURE__ */ jsx2("div", { className: "rounded-lg bg-red-500/10 border border-red-500/30 px-3 py-2", children: /* @__PURE__ */ jsx2("p", { className: "text-xs text-red-400", children: error }) }),
364
- step === "email" && /* @__PURE__ */ jsxs("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
365
- /* @__PURE__ */ jsx2(
366
- Input,
367
- {
368
- type: "email",
369
- placeholder: "you@company.com",
370
- value: email,
371
- onChange: setEmail,
372
- autoFocus: true,
373
- required: true
374
- }
375
- ),
376
- /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Continue" })
456
+ info && /* @__PURE__ */ jsx2("div", { className: "rounded-lg bg-blue-500/10 border border-blue-500/30 px-3 py-2", children: /* @__PURE__ */ jsx2("p", { className: "text-xs text-blue-400", children: info }) }),
457
+ step === "email" && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
458
+ /* @__PURE__ */ jsx2(GoogleButton, { onClick: handleGoogleSignIn }),
459
+ /* @__PURE__ */ jsx2(Divider, {}),
460
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
461
+ /* @__PURE__ */ jsx2(
462
+ Input,
463
+ {
464
+ type: "email",
465
+ placeholder: "you@company.com",
466
+ value: email,
467
+ onChange: setEmail,
468
+ autoFocus: true,
469
+ required: true
470
+ }
471
+ ),
472
+ /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Continue" })
473
+ ] })
377
474
  ] }),
378
475
  step === "password" && /* @__PURE__ */ jsxs("form", { onSubmit: handlePasswordSubmit, className: "space-y-3", children: [
379
476
  /* @__PURE__ */ jsx2(
@@ -388,6 +485,10 @@ function SignIn({
388
485
  }
389
486
  ),
390
487
  /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Sign in" }),
488
+ /* @__PURE__ */ jsx2(GhostButton, { onClick: () => {
489
+ setStep("forgot");
490
+ setError(null);
491
+ }, children: "Forgot password?" }),
391
492
  /* @__PURE__ */ jsx2(GhostButton, { onClick: () => setStep("email"), children: "\u2190 Back" })
392
493
  ] }),
393
494
  step === "passkey" && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
@@ -416,6 +517,58 @@ function SignIn({
416
517
  ),
417
518
  /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Verify" }),
418
519
  /* @__PURE__ */ jsx2(GhostButton, { onClick: () => setStep("password"), children: "\u2190 Back" })
520
+ ] }),
521
+ step === "forgot" && /* @__PURE__ */ jsxs("form", { onSubmit: handleForgotSubmit, className: "space-y-3", children: [
522
+ /* @__PURE__ */ jsx2(
523
+ Input,
524
+ {
525
+ type: "email",
526
+ placeholder: "you@company.com",
527
+ value: email,
528
+ onChange: setEmail,
529
+ autoFocus: true,
530
+ required: true
531
+ }
532
+ ),
533
+ /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Send reset code" }),
534
+ /* @__PURE__ */ jsx2(GhostButton, { onClick: () => {
535
+ setStep("password");
536
+ setError(null);
537
+ }, children: "\u2190 Back" })
538
+ ] }),
539
+ step === "forgot-verify" && /* @__PURE__ */ jsxs("form", { onSubmit: handleForgotVerifySubmit, className: "space-y-3", children: [
540
+ /* @__PURE__ */ jsx2(
541
+ Input,
542
+ {
543
+ type: "text",
544
+ inputMode: "numeric",
545
+ pattern: "[0-9]{6}",
546
+ maxLength: 6,
547
+ placeholder: "000000",
548
+ value: forgotCode,
549
+ onChange: setForgotCode,
550
+ autoFocus: true,
551
+ required: true,
552
+ className: "text-center tracking-[0.4em] text-lg"
553
+ }
554
+ ),
555
+ /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Continue" })
556
+ ] }),
557
+ step === "forgot-reset" && /* @__PURE__ */ jsxs("form", { onSubmit: handleResetPasswordSubmit, className: "space-y-3", children: [
558
+ /* @__PURE__ */ jsx2(
559
+ Input,
560
+ {
561
+ type: "password",
562
+ placeholder: "New password",
563
+ value: newPassword,
564
+ onChange: setNewPassword,
565
+ autoFocus: true,
566
+ required: true,
567
+ minLength: 8
568
+ }
569
+ ),
570
+ /* @__PURE__ */ jsx2(PasswordStrength, { password: newPassword }),
571
+ /* @__PURE__ */ jsx2(PrimaryButton, { loading, children: "Reset password" })
419
572
  ] })
420
573
  ] })
421
574
  ]
@@ -468,28 +621,63 @@ function GhostButton({ children, onClick }) {
468
621
  }
469
622
  );
470
623
  }
471
- function Spinner() {
624
+ function GoogleButton({ onClick }) {
472
625
  return /* @__PURE__ */ jsxs(
473
- "svg",
626
+ "button",
474
627
  {
475
- className: "animate-spin h-4 w-4 text-white/80",
476
- xmlns: "http://www.w3.org/2000/svg",
477
- fill: "none",
478
- viewBox: "0 0 24 24",
628
+ type: "button",
629
+ onClick,
630
+ className: clsx(
631
+ "w-full flex items-center justify-center gap-3 px-4 py-2.5 rounded-xl",
632
+ "text-sm font-medium text-white/80",
633
+ "bg-white/5 border border-white/10",
634
+ "hover:bg-white/10 hover:border-white/20",
635
+ "transition-all duration-150"
636
+ ),
479
637
  children: [
480
- /* @__PURE__ */ jsx2("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
481
- /* @__PURE__ */ jsx2(
482
- "path",
483
- {
484
- className: "opacity-75",
485
- fill: "currentColor",
486
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
487
- }
488
- )
638
+ /* @__PURE__ */ jsx2(GoogleIcon, {}),
639
+ "Continue with Google"
489
640
  ]
490
641
  }
491
642
  );
492
643
  }
644
+ function Divider() {
645
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
646
+ /* @__PURE__ */ jsx2("div", { className: "flex-1 h-px bg-white/8" }),
647
+ /* @__PURE__ */ jsx2("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
648
+ /* @__PURE__ */ jsx2("div", { className: "flex-1 h-px bg-white/8" })
649
+ ] });
650
+ }
651
+ function PasswordStrength({ password }) {
652
+ const score = (() => {
653
+ if (password.length === 0) return 0;
654
+ let s = 0;
655
+ if (password.length >= 8) s++;
656
+ if (/[A-Z]/.test(password)) s++;
657
+ if (/[0-9]/.test(password)) s++;
658
+ if (/[^A-Za-z0-9]/.test(password)) s++;
659
+ return s;
660
+ })();
661
+ if (password.length === 0) return null;
662
+ const labels = ["", "Weak", "Fair", "Good", "Strong"];
663
+ const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
664
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
665
+ /* @__PURE__ */ jsx2("div", { className: "flex gap-1", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx2(
666
+ "div",
667
+ {
668
+ className: clsx("flex-1 h-0.5 rounded-full transition-all duration-300", i <= score ? colors[score] : "bg-white/10")
669
+ },
670
+ i
671
+ )) }),
672
+ /* @__PURE__ */ jsx2("p", { className: "text-[10px] text-[#475569]", children: labels[score] })
673
+ ] });
674
+ }
675
+ function Spinner() {
676
+ return /* @__PURE__ */ 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: [
677
+ /* @__PURE__ */ jsx2("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
678
+ /* @__PURE__ */ jsx2("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
679
+ ] });
680
+ }
493
681
  function LockIcon() {
494
682
  return /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
495
683
  /* @__PURE__ */ jsx2("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
@@ -506,6 +694,14 @@ function FingerprintIcon() {
506
694
  /* @__PURE__ */ jsx2("path", { d: "M12 12v.01" })
507
695
  ] });
508
696
  }
697
+ function GoogleIcon() {
698
+ return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: [
699
+ /* @__PURE__ */ jsx2("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" }),
700
+ /* @__PURE__ */ jsx2("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" }),
701
+ /* @__PURE__ */ jsx2("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" }),
702
+ /* @__PURE__ */ jsx2("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" })
703
+ ] });
704
+ }
509
705
 
510
706
  // src/components/SignUp.tsx
511
707
  import { clsx as clsx2 } from "clsx";
@@ -519,6 +715,18 @@ function resolveApiOrigin3(prop) {
519
715
  }
520
716
  return "";
521
717
  }
718
+ function resolveAfterSignUpUrl(redirectUrlProp) {
719
+ if (redirectUrlProp) return redirectUrlProp;
720
+ if (typeof document !== "undefined") {
721
+ const el = document.querySelector("[data-vaultix-after-sign-up]");
722
+ const attr = el?.getAttribute("data-vaultix-after-sign-up");
723
+ if (attr) return attr;
724
+ const params = new URLSearchParams(window.location.search);
725
+ const redirectUrl = params.get("redirect_url");
726
+ if (redirectUrl) return redirectUrl;
727
+ }
728
+ return "/";
729
+ }
522
730
  function SignUp({
523
731
  redirectUrl,
524
732
  onSuccess,
@@ -538,6 +746,18 @@ function SignUp({
538
746
  setError(msg);
539
747
  onError?.(msg);
540
748
  }
749
+ function handleSuccess(handshakeToken) {
750
+ onSuccess?.(handshakeToken);
751
+ const target = resolveAfterSignUpUrl(redirectUrl);
752
+ const url = new URL(target, window.location.origin);
753
+ url.searchParams.set("__vaultix_handshake", handshakeToken);
754
+ window.location.href = url.toString();
755
+ }
756
+ function handleGoogleSignUp() {
757
+ const target = resolveAfterSignUpUrl(redirectUrl);
758
+ const params = new URLSearchParams({ redirect_url: target });
759
+ window.location.href = `${apiOrigin}/v1/auth/oauth/google?${params}`;
760
+ }
541
761
  async function handleEmailPassword(e) {
542
762
  e.preventDefault();
543
763
  setError(null);
@@ -581,9 +801,7 @@ function SignUp({
581
801
  setErr(data.error ?? "Invalid code.");
582
802
  return;
583
803
  }
584
- onSuccess?.(data.session_id);
585
- const target = redirectUrl ?? document.querySelector("[data-vaultix-after-sign-up]")?.getAttribute("data-vaultix-after-sign-up") ?? "/";
586
- if (target) window.location.href = target;
804
+ handleSuccess(data.handshake_token);
587
805
  } catch {
588
806
  setErr("Network error. Please try again.");
589
807
  } finally {
@@ -618,31 +836,35 @@ function SignUp({
618
836
  ] }),
619
837
  /* @__PURE__ */ jsxs2("div", { className: "px-8 pb-8 space-y-4", children: [
620
838
  error && /* @__PURE__ */ jsx3("div", { className: "rounded-lg bg-red-500/10 border border-red-500/30 px-3 py-2", children: /* @__PURE__ */ jsx3("p", { className: "text-xs text-red-400", children: error }) }),
621
- (step === "email" || step === "password") && /* @__PURE__ */ jsxs2("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
622
- /* @__PURE__ */ jsx3(
623
- SignUpInput,
624
- {
625
- type: "email",
626
- placeholder: "you@company.com",
627
- value: email,
628
- onChange: setEmail,
629
- autoFocus: true,
630
- required: true
631
- }
632
- ),
633
- /* @__PURE__ */ jsx3(
634
- SignUpInput,
635
- {
636
- type: "password",
637
- placeholder: "Create a password",
638
- value: password,
639
- onChange: setPassword,
640
- required: true,
641
- minLength: 8
642
- }
643
- ),
644
- /* @__PURE__ */ jsx3(PasswordStrength, { password }),
645
- /* @__PURE__ */ jsx3(SignUpPrimaryButton, { loading, children: "Create account" })
839
+ step === "email" && /* @__PURE__ */ jsxs2("div", { className: "space-y-3", children: [
840
+ /* @__PURE__ */ jsx3(GoogleButton2, { onClick: handleGoogleSignUp }),
841
+ /* @__PURE__ */ jsx3(Divider2, {}),
842
+ /* @__PURE__ */ jsxs2("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
843
+ /* @__PURE__ */ jsx3(
844
+ SignUpInput,
845
+ {
846
+ type: "email",
847
+ placeholder: "you@company.com",
848
+ value: email,
849
+ onChange: setEmail,
850
+ autoFocus: true,
851
+ required: true
852
+ }
853
+ ),
854
+ /* @__PURE__ */ jsx3(
855
+ SignUpInput,
856
+ {
857
+ type: "password",
858
+ placeholder: "Create a password",
859
+ value: password,
860
+ onChange: setPassword,
861
+ required: true,
862
+ minLength: 8
863
+ }
864
+ ),
865
+ /* @__PURE__ */ jsx3(PasswordStrength2, { password }),
866
+ /* @__PURE__ */ jsx3(SignUpPrimaryButton, { loading, children: "Create account" })
867
+ ] })
646
868
  ] }),
647
869
  step === "verify" && /* @__PURE__ */ jsxs2("form", { onSubmit: handleVerification, className: "space-y-3", children: [
648
870
  /* @__PURE__ */ jsx3(
@@ -712,7 +934,34 @@ function SignUpPrimaryButton({
712
934
  }
713
935
  );
714
936
  }
715
- function PasswordStrength({ password }) {
937
+ function GoogleButton2({ onClick }) {
938
+ return /* @__PURE__ */ jsxs2(
939
+ "button",
940
+ {
941
+ type: "button",
942
+ onClick,
943
+ className: clsx2(
944
+ "w-full flex items-center justify-center gap-3 px-4 py-2.5 rounded-xl",
945
+ "text-sm font-medium text-white/80",
946
+ "bg-white/5 border border-white/10",
947
+ "hover:bg-white/10 hover:border-white/20",
948
+ "transition-all duration-150"
949
+ ),
950
+ children: [
951
+ /* @__PURE__ */ jsx3(GoogleIcon2, {}),
952
+ "Continue with Google"
953
+ ]
954
+ }
955
+ );
956
+ }
957
+ function Divider2() {
958
+ return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3", children: [
959
+ /* @__PURE__ */ jsx3("div", { className: "flex-1 h-px bg-white/8" }),
960
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
961
+ /* @__PURE__ */ jsx3("div", { className: "flex-1 h-px bg-white/8" })
962
+ ] });
963
+ }
964
+ function PasswordStrength2({ password }) {
716
965
  const score = (() => {
717
966
  if (password.length === 0) return 0;
718
967
  let s = 0;
@@ -724,13 +973,7 @@ function PasswordStrength({ password }) {
724
973
  })();
725
974
  if (password.length === 0) return null;
726
975
  const labels = ["", "Weak", "Fair", "Good", "Strong"];
727
- const colors = [
728
- "",
729
- "bg-red-500",
730
- "bg-amber-400",
731
- "bg-blue-400",
732
- "bg-emerald-400"
733
- ];
976
+ const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
734
977
  return /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
735
978
  /* @__PURE__ */ jsx3("div", { className: "flex gap-1", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx3(
736
979
  "div",
@@ -746,35 +989,61 @@ function PasswordStrength({ password }) {
746
989
  ] });
747
990
  }
748
991
  function Spinner2() {
749
- return /* @__PURE__ */ jsxs2(
750
- "svg",
751
- {
752
- className: "animate-spin h-4 w-4 text-white/80",
753
- xmlns: "http://www.w3.org/2000/svg",
754
- fill: "none",
755
- viewBox: "0 0 24 24",
756
- children: [
757
- /* @__PURE__ */ jsx3("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
758
- /* @__PURE__ */ jsx3(
759
- "path",
760
- {
761
- className: "opacity-75",
762
- fill: "currentColor",
763
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
764
- }
765
- )
766
- ]
767
- }
768
- );
992
+ return /* @__PURE__ */ jsxs2("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: [
993
+ /* @__PURE__ */ jsx3("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
994
+ /* @__PURE__ */ jsx3("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
995
+ ] });
769
996
  }
770
997
  function SparkleIcon() {
771
998
  return /* @__PURE__ */ jsx3("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("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" }) });
772
999
  }
1000
+ function GoogleIcon2() {
1001
+ return /* @__PURE__ */ jsxs2("svg", { width: "16", height: "16", viewBox: "0 0 24 24", children: [
1002
+ /* @__PURE__ */ jsx3("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" }),
1003
+ /* @__PURE__ */ jsx3("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" }),
1004
+ /* @__PURE__ */ jsx3("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" }),
1005
+ /* @__PURE__ */ jsx3("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" })
1006
+ ] });
1007
+ }
1008
+
1009
+ // src/components/SignedIn.tsx
1010
+ import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
1011
+ function SignedIn({ children }) {
1012
+ const { isLoaded, isSignedIn } = useVaultixContext();
1013
+ if (!isLoaded || !isSignedIn) return null;
1014
+ return /* @__PURE__ */ jsx4(Fragment, { children });
1015
+ }
1016
+ function SignedOut({ children }) {
1017
+ const { isLoaded, isSignedIn } = useVaultixContext();
1018
+ if (!isLoaded || isSignedIn) return null;
1019
+ return /* @__PURE__ */ jsx4(Fragment, { children });
1020
+ }
1021
+
1022
+ // src/components/RedirectComponents.tsx
1023
+ import { useEffect as useEffect2 } from "react";
1024
+ function RedirectToSignIn({ redirectUrl = "/sign-in" }) {
1025
+ const { isLoaded, isSignedIn } = useVaultixContext();
1026
+ useEffect2(() => {
1027
+ if (isLoaded && !isSignedIn) {
1028
+ window.location.href = redirectUrl;
1029
+ }
1030
+ }, [isLoaded, isSignedIn, redirectUrl]);
1031
+ return null;
1032
+ }
1033
+ function RedirectToSignUp({ redirectUrl = "/sign-up" }) {
1034
+ const { isLoaded, isSignedIn } = useVaultixContext();
1035
+ useEffect2(() => {
1036
+ if (isLoaded && !isSignedIn) {
1037
+ window.location.href = redirectUrl;
1038
+ }
1039
+ }, [isLoaded, isSignedIn, redirectUrl]);
1040
+ return null;
1041
+ }
773
1042
 
774
1043
  // src/components/UserButton.tsx
775
1044
  import { clsx as clsx3 } from "clsx";
776
- import { useEffect as useEffect2, useRef as useRef3, useState as useState4 } from "react";
777
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1045
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
1046
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
778
1047
  function UserButton({
779
1048
  showName = false,
780
1049
  afterSignOutUrl,
@@ -784,7 +1053,7 @@ function UserButton({
784
1053
  const [open, setOpen] = useState4(false);
785
1054
  const [signingOut, setSigningOut] = useState4(false);
786
1055
  const containerRef = useRef3(null);
787
- useEffect2(() => {
1056
+ useEffect3(() => {
788
1057
  function onPointerDown(e) {
789
1058
  if (containerRef.current && !containerRef.current.contains(e.target)) {
790
1059
  setOpen(false);
@@ -793,7 +1062,7 @@ function UserButton({
793
1062
  document.addEventListener("pointerdown", onPointerDown);
794
1063
  return () => document.removeEventListener("pointerdown", onPointerDown);
795
1064
  }, []);
796
- if (!isLoaded) return /* @__PURE__ */ jsx4(AvatarSkeleton, {});
1065
+ if (!isLoaded) return /* @__PURE__ */ jsx5(AvatarSkeleton, {});
797
1066
  if (!isSignedIn || !user) return null;
798
1067
  const initials = [user.firstName, user.lastName].filter(Boolean).map((s) => s.charAt(0)).join("").toUpperCase() || user.email.charAt(0).toUpperCase();
799
1068
  async function handleSignOut() {
@@ -808,8 +1077,8 @@ function UserButton({
808
1077
  onClick: () => setOpen((o) => !o),
809
1078
  className: "flex items-center gap-2 rounded-xl p-1 hover:bg-white/8 transition-colors",
810
1079
  children: [
811
- /* @__PURE__ */ jsx4(Avatar, { initials, imageUrl: user.imageUrl }),
812
- showName && /* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-white/90 pr-1", children: user.firstName ?? user.email })
1080
+ /* @__PURE__ */ jsx5(Avatar, { initials, imageUrl: user.imageUrl }),
1081
+ showName && /* @__PURE__ */ jsx5("span", { className: "text-sm font-medium text-white/90 pr-1", children: user.firstName ?? user.email })
813
1082
  ]
814
1083
  }
815
1084
  ),
@@ -823,39 +1092,39 @@ function UserButton({
823
1092
  style: { background: "rgba(22,27,45,0.96)" },
824
1093
  children: [
825
1094
  /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-white/8", children: [
826
- /* @__PURE__ */ jsx4(Avatar, { initials, imageUrl: user.imageUrl, size: "lg" }),
1095
+ /* @__PURE__ */ jsx5(Avatar, { initials, imageUrl: user.imageUrl, size: "lg" }),
827
1096
  /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
828
- (user.firstName || user.lastName) && /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-white/90 truncate", children: [user.firstName, user.lastName].filter(Boolean).join(" ") }),
829
- /* @__PURE__ */ jsx4("p", { className: "text-xs text-[#475569] truncate", children: user.email })
1097
+ (user.firstName || user.lastName) && /* @__PURE__ */ jsx5("p", { className: "text-sm font-semibold text-white/90 truncate", children: [user.firstName, user.lastName].filter(Boolean).join(" ") }),
1098
+ /* @__PURE__ */ jsx5("p", { className: "text-xs text-[#475569] truncate", children: user.email })
830
1099
  ] })
831
1100
  ] }),
832
- session && /* @__PURE__ */ jsx4("div", { className: "px-4 py-2 border-b border-white/8", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
833
- /* @__PURE__ */ jsx4("span", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Risk level" }),
834
- /* @__PURE__ */ jsx4(RiskBadge, { level: session.riskLevel })
1101
+ session && /* @__PURE__ */ jsx5("div", { className: "px-4 py-2 border-b border-white/8", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
1102
+ /* @__PURE__ */ jsx5("span", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Risk level" }),
1103
+ /* @__PURE__ */ jsx5(RiskBadge, { level: session.riskLevel })
835
1104
  ] }) }),
836
1105
  /* @__PURE__ */ jsxs3("div", { className: "p-2", children: [
837
- /* @__PURE__ */ jsx4(
1106
+ /* @__PURE__ */ jsx5(
838
1107
  DropdownItem,
839
1108
  {
840
1109
  label: "Manage account",
841
- icon: /* @__PURE__ */ jsx4(UserIcon, {}),
1110
+ icon: /* @__PURE__ */ jsx5(UserIcon, {}),
842
1111
  onClick: () => setOpen(false)
843
1112
  }
844
1113
  ),
845
- /* @__PURE__ */ jsx4(
1114
+ /* @__PURE__ */ jsx5(
846
1115
  DropdownItem,
847
1116
  {
848
1117
  label: "Security settings",
849
- icon: /* @__PURE__ */ jsx4(ShieldIcon, {}),
1118
+ icon: /* @__PURE__ */ jsx5(ShieldIcon, {}),
850
1119
  onClick: () => setOpen(false)
851
1120
  }
852
1121
  ),
853
- /* @__PURE__ */ jsx4("div", { className: "h-px bg-white/8 my-1" }),
854
- /* @__PURE__ */ jsx4(
1122
+ /* @__PURE__ */ jsx5("div", { className: "h-px bg-white/8 my-1" }),
1123
+ /* @__PURE__ */ jsx5(
855
1124
  DropdownItem,
856
1125
  {
857
1126
  label: signingOut ? "Signing out\u2026" : "Sign out",
858
- icon: /* @__PURE__ */ jsx4(SignOutIcon, {}),
1127
+ icon: /* @__PURE__ */ jsx5(SignOutIcon, {}),
859
1128
  onClick: handleSignOut,
860
1129
  destructive: true
861
1130
  }
@@ -871,7 +1140,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
871
1140
  if (imageUrl) {
872
1141
  return (
873
1142
  // eslint-disable-next-line @next/next/no-img-element
874
- /* @__PURE__ */ jsx4(
1143
+ /* @__PURE__ */ jsx5(
875
1144
  "img",
876
1145
  {
877
1146
  src: imageUrl,
@@ -881,7 +1150,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
881
1150
  )
882
1151
  );
883
1152
  }
884
- return /* @__PURE__ */ jsx4(
1153
+ return /* @__PURE__ */ jsx5(
885
1154
  "div",
886
1155
  {
887
1156
  className: clsx3(
@@ -894,7 +1163,7 @@ function Avatar({ initials, imageUrl, size = "sm" }) {
894
1163
  );
895
1164
  }
896
1165
  function AvatarSkeleton() {
897
- return /* @__PURE__ */ jsx4("div", { className: "w-8 h-8 rounded-full bg-white/5 animate-pulse" });
1166
+ return /* @__PURE__ */ jsx5("div", { className: "w-8 h-8 rounded-full bg-white/5 animate-pulse" });
898
1167
  }
899
1168
  function RiskBadge({ level }) {
900
1169
  const styles = {
@@ -903,7 +1172,7 @@ function RiskBadge({ level }) {
903
1172
  high: "bg-orange-500/15 text-orange-400 border-orange-500/30",
904
1173
  critical: "bg-red-500/15 text-red-400 border-red-500/30"
905
1174
  };
906
- return /* @__PURE__ */ jsx4(
1175
+ return /* @__PURE__ */ jsx5(
907
1176
  "span",
908
1177
  {
909
1178
  className: clsx3(
@@ -924,7 +1193,7 @@ function DropdownItem({ label, icon, onClick, destructive }) {
924
1193
  destructive ? "text-red-400 hover:bg-red-500/10" : "text-white/70 hover:text-white hover:bg-white/8"
925
1194
  ),
926
1195
  children: [
927
- /* @__PURE__ */ jsx4("span", { className: "opacity-70", children: icon }),
1196
+ /* @__PURE__ */ jsx5("span", { className: "opacity-70", children: icon }),
928
1197
  label
929
1198
  ]
930
1199
  }
@@ -932,25 +1201,25 @@ function DropdownItem({ label, icon, onClick, destructive }) {
932
1201
  }
933
1202
  function UserIcon() {
934
1203
  return /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
935
- /* @__PURE__ */ jsx4("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }),
936
- /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "7", r: "4" })
1204
+ /* @__PURE__ */ jsx5("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }),
1205
+ /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "7", r: "4" })
937
1206
  ] });
938
1207
  }
939
1208
  function ShieldIcon() {
940
- return /* @__PURE__ */ jsx4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx4("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) });
1209
+ return /* @__PURE__ */ jsx5("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) });
941
1210
  }
942
1211
  function SignOutIcon() {
943
1212
  return /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
944
- /* @__PURE__ */ jsx4("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
945
- /* @__PURE__ */ jsx4("polyline", { points: "16 17 21 12 16 7" }),
946
- /* @__PURE__ */ jsx4("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
1213
+ /* @__PURE__ */ jsx5("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
1214
+ /* @__PURE__ */ jsx5("polyline", { points: "16 17 21 12 16 7" }),
1215
+ /* @__PURE__ */ jsx5("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
947
1216
  ] });
948
1217
  }
949
1218
 
950
1219
  // src/components/OrganizationSwitcher.tsx
951
1220
  import { clsx as clsx4 } from "clsx";
952
- import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
953
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1221
+ import { useEffect as useEffect4, useRef as useRef4, useState as useState5 } from "react";
1222
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
954
1223
  function resolveApiOrigin4() {
955
1224
  if (typeof document !== "undefined") {
956
1225
  const el = document.querySelector("[data-vaultix-api]");
@@ -967,7 +1236,7 @@ function OrganizationSwitcher({
967
1236
  const [orgs, setOrgs] = useState5([]);
968
1237
  const [switching, setSwitching] = useState5(null);
969
1238
  const containerRef = useRef4(null);
970
- useEffect3(() => {
1239
+ useEffect4(() => {
971
1240
  function onPointerDown(e) {
972
1241
  if (containerRef.current && !containerRef.current.contains(e.target)) {
973
1242
  setOpen(false);
@@ -976,7 +1245,7 @@ function OrganizationSwitcher({
976
1245
  document.addEventListener("pointerdown", onPointerDown);
977
1246
  return () => document.removeEventListener("pointerdown", onPointerDown);
978
1247
  }, []);
979
- useEffect3(() => {
1248
+ useEffect4(() => {
980
1249
  if (!open) return;
981
1250
  const api = resolveApiOrigin4();
982
1251
  fetch(`${api}/v1/me/organizations`, { credentials: "include" }).then((r) => r.json()).then(
@@ -1021,12 +1290,12 @@ function OrganizationSwitcher({
1021
1290
  "transition-all duration-150"
1022
1291
  ),
1023
1292
  children: [
1024
- /* @__PURE__ */ jsx5(OrgAvatar, { initials }),
1293
+ /* @__PURE__ */ jsx6(OrgAvatar, { initials }),
1025
1294
  /* @__PURE__ */ jsxs4("div", { className: "text-left min-w-0", children: [
1026
- /* @__PURE__ */ jsx5("p", { className: "text-sm font-semibold text-white/90 truncate max-w-[120px]", children: displayName }),
1027
- organization && /* @__PURE__ */ jsx5("p", { className: "text-[10px] text-[#475569] capitalize", children: organization.role })
1295
+ /* @__PURE__ */ jsx6("p", { className: "text-sm font-semibold text-white/90 truncate max-w-[120px]", children: displayName }),
1296
+ organization && /* @__PURE__ */ jsx6("p", { className: "text-[10px] text-[#475569] capitalize", children: organization.role })
1028
1297
  ] }),
1029
- /* @__PURE__ */ jsx5(ChevronIcon, {})
1298
+ /* @__PURE__ */ jsx6(ChevronIcon, {})
1030
1299
  ]
1031
1300
  }
1032
1301
  ),
@@ -1039,9 +1308,9 @@ function OrganizationSwitcher({
1039
1308
  ),
1040
1309
  style: { background: "rgba(22,27,45,0.96)" },
1041
1310
  children: [
1042
- /* @__PURE__ */ jsx5("div", { className: "px-4 py-3 border-b border-white/8", children: /* @__PURE__ */ jsx5("p", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Switch organization" }) }),
1311
+ /* @__PURE__ */ jsx6("div", { className: "px-4 py-3 border-b border-white/8", children: /* @__PURE__ */ jsx6("p", { className: "text-[10px] uppercase tracking-widest text-[#475569]", children: "Switch organization" }) }),
1043
1312
  /* @__PURE__ */ jsxs4("div", { className: "p-2 max-h-56 overflow-y-auto", children: [
1044
- orgs.length === 0 && /* @__PURE__ */ jsx5("p", { className: "text-xs text-[#475569] text-center py-4", children: "Loading\u2026" }),
1313
+ orgs.length === 0 && /* @__PURE__ */ jsx6("p", { className: "text-xs text-[#475569] text-center py-4", children: "Loading\u2026" }),
1045
1314
  orgs.map((org) => {
1046
1315
  const isActive = org.id === organization?.id;
1047
1316
  const orgInitials = org.name.split(/\s+/).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
@@ -1055,9 +1324,9 @@ function OrganizationSwitcher({
1055
1324
  isActive ? "bg-purple-500/10 cursor-default" : "hover:bg-white/8 cursor-pointer"
1056
1325
  ),
1057
1326
  children: [
1058
- /* @__PURE__ */ jsx5(OrgAvatar, { initials: orgInitials, active: isActive }),
1327
+ /* @__PURE__ */ jsx6(OrgAvatar, { initials: orgInitials, active: isActive }),
1059
1328
  /* @__PURE__ */ jsxs4("div", { className: "flex-1 min-w-0", children: [
1060
- /* @__PURE__ */ jsx5(
1329
+ /* @__PURE__ */ jsx6(
1061
1330
  "p",
1062
1331
  {
1063
1332
  className: clsx4(
@@ -1067,17 +1336,17 @@ function OrganizationSwitcher({
1067
1336
  children: org.name
1068
1337
  }
1069
1338
  ),
1070
- /* @__PURE__ */ jsx5("p", { className: "text-[10px] text-[#475569] capitalize", children: org.role })
1339
+ /* @__PURE__ */ jsx6("p", { className: "text-[10px] text-[#475569] capitalize", children: org.role })
1071
1340
  ] }),
1072
- isActive && /* @__PURE__ */ jsx5("span", { className: "w-1.5 h-1.5 rounded-full bg-purple-400 shrink-0" }),
1073
- switching === org.id && /* @__PURE__ */ jsx5(MiniSpinner, {})
1341
+ isActive && /* @__PURE__ */ jsx6("span", { className: "w-1.5 h-1.5 rounded-full bg-purple-400 shrink-0" }),
1342
+ switching === org.id && /* @__PURE__ */ jsx6(MiniSpinner, {})
1074
1343
  ]
1075
1344
  },
1076
1345
  org.id
1077
1346
  );
1078
1347
  })
1079
1348
  ] }),
1080
- /* @__PURE__ */ jsx5("div", { className: "p-2 border-t border-white/8", children: /* @__PURE__ */ jsxs4(
1349
+ /* @__PURE__ */ jsx6("div", { className: "p-2 border-t border-white/8", children: /* @__PURE__ */ jsxs4(
1081
1350
  "button",
1082
1351
  {
1083
1352
  onClick: () => {
@@ -1085,7 +1354,7 @@ function OrganizationSwitcher({
1085
1354
  },
1086
1355
  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",
1087
1356
  children: [
1088
- /* @__PURE__ */ jsx5(PlusIcon, {}),
1357
+ /* @__PURE__ */ jsx6(PlusIcon, {}),
1089
1358
  "Create organization"
1090
1359
  ]
1091
1360
  }
@@ -1099,7 +1368,7 @@ function OrgAvatar({
1099
1368
  initials,
1100
1369
  active = false
1101
1370
  }) {
1102
- return /* @__PURE__ */ jsx5(
1371
+ return /* @__PURE__ */ jsx6(
1103
1372
  "div",
1104
1373
  {
1105
1374
  className: clsx4(
@@ -1111,7 +1380,7 @@ function OrgAvatar({
1111
1380
  );
1112
1381
  }
1113
1382
  function ChevronIcon() {
1114
- return /* @__PURE__ */ jsx5(
1383
+ return /* @__PURE__ */ jsx6(
1115
1384
  "svg",
1116
1385
  {
1117
1386
  width: "12",
@@ -1123,28 +1392,33 @@ function ChevronIcon() {
1123
1392
  strokeLinecap: "round",
1124
1393
  strokeLinejoin: "round",
1125
1394
  className: "text-[#475569] shrink-0",
1126
- children: /* @__PURE__ */ jsx5("polyline", { points: "6 9 12 15 18 9" })
1395
+ children: /* @__PURE__ */ jsx6("polyline", { points: "6 9 12 15 18 9" })
1127
1396
  }
1128
1397
  );
1129
1398
  }
1130
1399
  function PlusIcon() {
1131
1400
  return /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1132
- /* @__PURE__ */ jsx5("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1133
- /* @__PURE__ */ jsx5("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1401
+ /* @__PURE__ */ jsx6("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
1402
+ /* @__PURE__ */ jsx6("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
1134
1403
  ] });
1135
1404
  }
1136
1405
  function MiniSpinner() {
1137
1406
  return /* @__PURE__ */ jsxs4("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: [
1138
- /* @__PURE__ */ jsx5("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1139
- /* @__PURE__ */ jsx5("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
1407
+ /* @__PURE__ */ jsx6("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1408
+ /* @__PURE__ */ jsx6("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
1140
1409
  ] });
1141
1410
  }
1142
1411
  export {
1143
1412
  OrganizationSwitcher,
1413
+ RedirectToSignIn,
1414
+ RedirectToSignUp,
1144
1415
  SignIn,
1145
1416
  SignUp,
1417
+ SignedIn,
1418
+ SignedOut,
1146
1419
  UserButton,
1147
1420
  VaultixProvider,
1421
+ useAuth,
1148
1422
  useOrganization,
1149
1423
  useSession,
1150
1424
  useUser,