@vaultix.ai/react 0.3.3 → 0.3.5

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.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  getStoredToken: () => getStoredToken,
34
34
  useAuth: () => useAuth,
35
35
  useOrganization: () => useOrganization,
36
+ usePlatformConnect: () => usePlatformConnect,
36
37
  useSession: () => useSession,
37
38
  useUser: () => useUser,
38
39
  useVaultix: () => useVaultix
@@ -111,6 +112,7 @@ function VaultixProvider({
111
112
  const [user, setUser] = (0, import_react.useState)(null);
112
113
  const [session, setSession] = (0, import_react.useState)(null);
113
114
  const [organization, setOrganization] = (0, import_react.useState)(null);
115
+ const [appConfig, setAppConfig] = (0, import_react.useState)(null);
114
116
  const jwtRef = (0, import_react.useRef)(null);
115
117
  const refreshTimerRef = (0, import_react.useRef)(null);
116
118
  const clearAuth = (0, import_react.useCallback)(() => {
@@ -211,7 +213,21 @@ function VaultixProvider({
211
213
  if (!cancelled) setIsLoaded(true);
212
214
  }
213
215
  }
216
+ async function fetchAppConfig() {
217
+ try {
218
+ const res = await fetch(
219
+ `${apiOrigin}/api/v1/app/config?pk=${encodeURIComponent(publishableKey)}`,
220
+ { credentials: "omit" }
221
+ );
222
+ if (res.ok && !cancelled) {
223
+ const cfg = await res.json();
224
+ setAppConfig(cfg);
225
+ }
226
+ } catch {
227
+ }
228
+ }
214
229
  hydrate();
230
+ void fetchAppConfig();
215
231
  return () => {
216
232
  cancelled = true;
217
233
  if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
@@ -270,6 +286,7 @@ function VaultixProvider({
270
286
  isLoaded,
271
287
  isSignedIn: !!session,
272
288
  apiOrigin,
289
+ appConfig,
273
290
  signOut,
274
291
  updateUser,
275
292
  connectPlatform
@@ -304,6 +321,44 @@ function useOrganization() {
304
321
  const { organization, isLoaded } = useVaultixContext();
305
322
  return { organization, isLoaded };
306
323
  }
324
+ function usePlatformConnect(provider, defaultOptions) {
325
+ const { connectPlatform } = useVaultixContext();
326
+ const [connectedAccount, setConnectedAccount] = (0, import_react2.useState)(null);
327
+ const connect = (0, import_react2.useCallback)(
328
+ (overrides) => {
329
+ connectPlatform(provider, { ...defaultOptions, ...overrides });
330
+ },
331
+ [connectPlatform, provider, defaultOptions]
332
+ );
333
+ (0, import_react2.useEffect)(() => {
334
+ if (typeof window === "undefined") return;
335
+ const params = new URLSearchParams(window.location.search);
336
+ const connectToken = params.get("__vaultix_connect");
337
+ const returnedProvider = params.get("provider");
338
+ if (!connectToken || returnedProvider !== provider) return;
339
+ try {
340
+ const segment = connectToken.split(".")[1];
341
+ if (!segment) return;
342
+ const b64 = segment.replace(/-/g, "+").replace(/_/g, "/");
343
+ const payload = JSON.parse(atob(b64));
344
+ const result = {
345
+ provider: returnedProvider,
346
+ raw: payload,
347
+ ...typeof payload["platform_user_id"] === "string" && { platformUserId: payload["platform_user_id"] },
348
+ ...typeof payload["username"] === "string" && { username: payload["username"] },
349
+ ...typeof payload["access_token"] === "string" && { accessToken: payload["access_token"] },
350
+ ...typeof payload["scope"] === "string" && { scope: payload["scope"] }
351
+ };
352
+ setConnectedAccount(result);
353
+ const clean = new URL(window.location.href);
354
+ clean.searchParams.delete("__vaultix_connect");
355
+ clean.searchParams.delete("provider");
356
+ window.history.replaceState({}, "", clean.toString());
357
+ } catch {
358
+ }
359
+ }, [provider]);
360
+ return { connect, connectedAccount };
361
+ }
307
362
  function useAuth() {
308
363
  const { user, session, isLoaded, isSignedIn, signOut } = useVaultixContext();
309
364
  const getToken = (0, import_react2.useCallback)(async () => {
@@ -365,9 +420,25 @@ function SignIn({
365
420
  onSuccess,
366
421
  onError,
367
422
  apiOrigin: apiOriginProp,
368
- className
423
+ className,
424
+ appearance
369
425
  }) {
370
426
  const apiOrigin = resolveApiOrigin2(apiOriginProp);
427
+ const vars = appearance?.variables ?? {};
428
+ const primaryColor = vars.colorPrimary;
429
+ const cardBg = vars.colorBackground ?? "rgba(22,27,45,0.92)";
430
+ const textColor = vars.colorText ?? "rgba(255,255,255,0.9)";
431
+ const mutedColor = vars.colorTextMuted ?? "#475569";
432
+ let appConfig = null;
433
+ try {
434
+ appConfig = useVaultixContext().appConfig;
435
+ } catch {
436
+ }
437
+ const enabledProviders = appConfig?.providers ?? ["google", "github", "meta", "linkedin", "x", "threads"];
438
+ const enabledMethods = appConfig?.methods ?? ["password", "magic_link", "passkey"];
439
+ const hasPassword = enabledMethods.includes("password");
440
+ const hasMagicLink = enabledMethods.includes("magic_link");
441
+ const hasPasskey = enabledMethods.includes("passkey");
371
442
  const [step, setStep] = (0, import_react3.useState)("email");
372
443
  const [email, setEmail] = (0, import_react3.useState)("");
373
444
  const [password, setPassword] = (0, import_react3.useState)("");
@@ -417,7 +488,15 @@ function SignIn({
417
488
  setErr(data.error ?? "Could not look up account.");
418
489
  return;
419
490
  }
420
- setStep(data.preferred_challenge === "passkey" ? "passkey" : "password");
491
+ if (data.preferred_challenge === "passkey" && hasPasskey) {
492
+ setStep("passkey");
493
+ } else if (hasPassword) {
494
+ setStep("password");
495
+ } else if (hasMagicLink) {
496
+ await handleMagicLinkRequest();
497
+ } else if (hasPasskey) {
498
+ setStep("passkey");
499
+ }
421
500
  } catch {
422
501
  setErr("Network error. Please try again.");
423
502
  } finally {
@@ -632,24 +711,31 @@ function SignIn({
632
711
  "backdrop-blur-[16px]",
633
712
  className
634
713
  ),
635
- style: { background: "rgba(22,27,45,0.92)" },
714
+ style: { background: cardBg },
636
715
  children: [
637
716
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-8 pt-8 pb-6 text-center", children: [
638
- /* @__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, {}) }),
639
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-xl font-semibold text-white/90", children: title[step] }),
640
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-[#475569] mt-1", children: subtitle[step] })
717
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
718
+ "div",
719
+ {
720
+ className: "inline-flex items-center justify-center w-10 h-10 rounded-xl shadow-lg mb-4",
721
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}4d` } : { background: "linear-gradient(to bottom right, #7c3aed, #2563eb)", boxShadow: "0 10px 15px -3px rgba(124,58,237,0.3)" },
722
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LockIcon, {})
723
+ }
724
+ ),
725
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-xl font-semibold", style: { color: textColor }, children: title[step] }),
726
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm mt-1", style: { color: mutedColor }, children: subtitle[step] })
641
727
  ] }),
642
728
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
643
729
  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 }) }),
644
730
  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 }) }),
645
731
  step === "email" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-3", children: [
646
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GoogleButton, { onClick: handleGoogleSignIn }),
647
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GitHubButton, { onClick: handleGitHubSignIn }),
648
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetaButton, { onClick: handleMetaSignIn }),
649
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LinkedInButton, { onClick: handleLinkedInSignIn }),
650
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XButton, { onClick: handleXSignIn }),
651
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Divider, {}),
652
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
732
+ enabledProviders.includes("google") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GoogleButton, { onClick: handleGoogleSignIn }),
733
+ enabledProviders.includes("github") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GitHubButton, { onClick: handleGitHubSignIn }),
734
+ enabledProviders.includes("meta") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetaButton, { onClick: handleMetaSignIn }),
735
+ enabledProviders.includes("linkedin") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LinkedInButton, { onClick: handleLinkedInSignIn }),
736
+ enabledProviders.includes("x") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XButton, { onClick: handleXSignIn }),
737
+ (hasPassword || hasMagicLink || hasPasskey) && enabledProviders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Divider, { mutedColor }),
738
+ (hasPassword || hasMagicLink || hasPasskey) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
653
739
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
654
740
  Input,
655
741
  {
@@ -658,10 +744,11 @@ function SignIn({
658
744
  value: email,
659
745
  onChange: setEmail,
660
746
  autoFocus: true,
661
- required: true
747
+ required: true,
748
+ primaryColor
662
749
  }
663
750
  ),
664
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Continue" })
665
752
  ] })
666
753
  ] }),
667
754
  step === "password" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handlePasswordSubmit, className: "space-y-3", children: [
@@ -673,42 +760,52 @@ function SignIn({
673
760
  value: password,
674
761
  onChange: setPassword,
675
762
  autoFocus: true,
676
- required: true
763
+ required: true,
764
+ primaryColor
677
765
  }
678
766
  ),
679
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Sign in" }),
680
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
681
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
682
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] text-[#475569]", children: "or" }),
683
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
767
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Sign in" }),
768
+ hasMagicLink && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
769
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
770
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
771
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px]", style: { color: mutedColor }, children: "or" }),
772
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
773
+ ] }),
774
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, mutedColor, children: "\u2709 Email me a sign-in link" })
684
775
  ] }),
685
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, children: "\u2709 Email me a sign-in link" }),
686
776
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
687
777
  setStep("forgot");
688
778
  setError(null);
689
- }, children: "Forgot password?" }),
690
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), children: "\u2190 Back" })
779
+ }, mutedColor, children: "Forgot password?" }),
780
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), mutedColor, children: "\u2190 Back" })
691
781
  ] }),
692
782
  step === "magic-link-sent" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-4 text-center", children: [
693
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-14 h-14 rounded-2xl bg-purple-500/15 border border-purple-500/30 flex items-center justify-center mx-auto", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EnvelopeIcon, {}) }),
694
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "text-sm text-[#94a3b8] leading-relaxed", children: [
783
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
784
+ "div",
785
+ {
786
+ className: "w-14 h-14 rounded-2xl flex items-center justify-center mx-auto border",
787
+ style: primaryColor ? { background: `${primaryColor}26`, borderColor: `${primaryColor}4d` } : { background: "rgba(168,85,247,0.15)", borderColor: "rgba(168,85,247,0.3)" },
788
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EnvelopeIcon, { color: primaryColor ?? "#a78bfa" })
789
+ }
790
+ ),
791
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "text-sm leading-relaxed", style: { color: mutedColor }, children: [
695
792
  "The link expires in ",
696
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-white/80 font-medium", children: "15 minutes" }),
793
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor }, className: "font-medium", children: "15 minutes" }),
697
794
  " and can only be used once."
698
795
  ] }),
699
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, children: "Resend link" }),
796
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, mutedColor, children: "Resend link" }),
700
797
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
701
798
  setStep("password");
702
799
  setError(null);
703
- }, children: "Use password instead" })
800
+ }, mutedColor, children: "Use password instead" })
704
801
  ] }),
705
802
  step === "passkey" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-3", children: [
706
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(PrimaryButton, { loading, onClick: handlePasskeySignIn, children: [
803
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(PrimaryButton, { loading, onClick: handlePasskeySignIn, primaryColor, children: [
707
804
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FingerprintIcon, {}),
708
805
  "Authenticate with passkey"
709
806
  ] }),
710
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), children: "Use password instead" }),
711
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), children: "\u2190 Back" })
807
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), mutedColor, children: "Use password instead" }),
808
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), mutedColor, children: "\u2190 Back" })
712
809
  ] }),
713
810
  step === "totp" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleTotpSubmit, className: "space-y-3", children: [
714
811
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -723,11 +820,12 @@ function SignIn({
723
820
  onChange: setTotp,
724
821
  autoFocus: true,
725
822
  required: true,
726
- className: "text-center tracking-[0.4em] text-lg"
823
+ className: "text-center tracking-[0.4em] text-lg",
824
+ primaryColor
727
825
  }
728
826
  ),
729
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Verify" }),
730
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), children: "\u2190 Back" })
827
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Verify" }),
828
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), mutedColor, children: "\u2190 Back" })
731
829
  ] }),
732
830
  step === "forgot" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotSubmit, className: "space-y-3", children: [
733
831
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -738,14 +836,15 @@ function SignIn({
738
836
  value: email,
739
837
  onChange: setEmail,
740
838
  autoFocus: true,
741
- required: true
839
+ required: true,
840
+ primaryColor
742
841
  }
743
842
  ),
744
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Send reset code" }),
843
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Send reset code" }),
745
844
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
746
845
  setStep("password");
747
846
  setError(null);
748
- }, children: "\u2190 Back" })
847
+ }, mutedColor, children: "\u2190 Back" })
749
848
  ] }),
750
849
  step === "forgot-verify" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotVerifySubmit, className: "space-y-3", children: [
751
850
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -760,10 +859,11 @@ function SignIn({
760
859
  onChange: setForgotCode,
761
860
  autoFocus: true,
762
861
  required: true,
763
- className: "text-center tracking-[0.4em] text-lg"
862
+ className: "text-center tracking-[0.4em] text-lg",
863
+ primaryColor
764
864
  }
765
865
  ),
766
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
866
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Continue" })
767
867
  ] }),
768
868
  step === "forgot-reset" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleResetPasswordSubmit, className: "space-y-3", children: [
769
869
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -775,18 +875,19 @@ function SignIn({
775
875
  onChange: setNewPassword,
776
876
  autoFocus: true,
777
877
  required: true,
778
- minLength: 8
878
+ minLength: 8,
879
+ primaryColor
779
880
  }
780
881
  ),
781
882
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PasswordStrength, { password: newPassword }),
782
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Reset password" })
883
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Reset password" })
783
884
  ] })
784
885
  ] })
785
886
  ]
786
887
  }
787
888
  );
788
889
  }
789
- function Input({ onChange, className, ...props }) {
890
+ function Input({ onChange, className, primaryColor, ...props }) {
790
891
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
791
892
  "input",
792
893
  {
@@ -795,39 +896,48 @@ function Input({ onChange, className, ...props }) {
795
896
  className: (0, import_clsx.clsx)(
796
897
  "w-full bg-white/5 border border-white/8 rounded-xl px-4 py-2.5",
797
898
  "text-sm text-white/90 placeholder:text-[#475569]",
798
- "focus:outline-none focus:border-purple-500/60 transition-colors",
899
+ "focus:outline-none transition-colors",
900
+ !primaryColor && "focus:border-purple-500/60",
799
901
  className
800
- )
902
+ ),
903
+ style: primaryColor ? { "--vx-focus": primaryColor } : void 0,
904
+ onFocus: (e) => {
905
+ if (primaryColor) e.currentTarget.style.borderColor = `${primaryColor}99`;
906
+ props.onFocus?.(e);
907
+ },
908
+ onBlur: (e) => {
909
+ if (primaryColor) e.currentTarget.style.borderColor = "";
910
+ props.onBlur?.(e);
911
+ }
801
912
  }
802
913
  );
803
914
  }
804
- function PrimaryButton({ children, loading, onClick }) {
915
+ function PrimaryButton({ children, loading, onClick, primaryColor }) {
805
916
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
806
917
  "button",
807
918
  {
808
919
  type: onClick ? "button" : "submit",
809
920
  onClick,
810
921
  disabled: loading,
922
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}33` } : void 0,
811
923
  className: (0, import_clsx.clsx)(
812
924
  "w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl",
813
- "text-sm font-semibold text-white",
814
- "bg-gradient-to-r from-purple-600 to-blue-600",
815
- "hover:from-purple-500 hover:to-blue-500",
816
- "shadow-lg shadow-purple-500/20",
817
- "transition-all duration-150",
818
- "disabled:opacity-60 disabled:cursor-not-allowed"
925
+ "text-sm font-semibold text-white transition-all duration-150",
926
+ "disabled:opacity-60 disabled:cursor-not-allowed",
927
+ !primaryColor && "bg-gradient-to-r from-purple-600 to-blue-600 hover:from-purple-500 hover:to-blue-500 shadow-lg shadow-purple-500/20"
819
928
  ),
820
929
  children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : children
821
930
  }
822
931
  );
823
932
  }
824
- function GhostButton({ children, onClick }) {
933
+ function GhostButton({ children, onClick, mutedColor }) {
825
934
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
826
935
  "button",
827
936
  {
828
937
  type: "button",
829
938
  onClick,
830
- className: "w-full text-xs text-[#475569] hover:text-white/70 transition-colors py-1",
939
+ className: "w-full text-xs transition-colors py-1 hover:opacity-80",
940
+ style: { color: mutedColor ?? "#475569" },
831
941
  children
832
942
  }
833
943
  );
@@ -871,10 +981,10 @@ function GitHubButton({ onClick }) {
871
981
  function XButton({ onClick }) {
872
982
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(OAuthButton, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XIcon, {}), label: "Continue with X", onClick });
873
983
  }
874
- function Divider() {
984
+ function Divider({ mutedColor }) {
875
985
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3", children: [
876
986
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
877
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
987
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] uppercase tracking-wider", style: { color: mutedColor ?? "#475569" }, children: "or" }),
878
988
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
879
989
  ] });
880
990
  }
@@ -944,8 +1054,8 @@ function GitHubIcon() {
944
1054
  function XIcon() {
945
1055
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.737-8.835L1.254 2.25H8.08l4.253 5.622 5.911-5.622zm-1.161 17.52h1.833L7.084 4.126H5.117z" }) });
946
1056
  }
947
- function EnvelopeIcon() {
948
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#a78bfa", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1057
+ function EnvelopeIcon({ color = "#a78bfa" }) {
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
949
1059
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
950
1060
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
951
1061
  ] });
@@ -963,6 +1073,13 @@ function resolveApiOrigin3(prop) {
963
1073
  }
964
1074
  return "";
965
1075
  }
1076
+ function resolvePk2() {
1077
+ if (typeof document !== "undefined") {
1078
+ const el = document.querySelector("[data-vaultix-pk]");
1079
+ if (el) return el.getAttribute("data-vaultix-pk") ?? "";
1080
+ }
1081
+ return "";
1082
+ }
966
1083
  function resolveAfterSignUpUrl(redirectUrlProp) {
967
1084
  if (redirectUrlProp) return redirectUrlProp;
968
1085
  if (typeof document !== "undefined") {
@@ -980,9 +1097,23 @@ function SignUp({
980
1097
  onSuccess,
981
1098
  onError,
982
1099
  apiOrigin: apiOriginProp,
983
- className
1100
+ className,
1101
+ appearance
984
1102
  }) {
985
1103
  const apiOrigin = resolveApiOrigin3(apiOriginProp);
1104
+ const vars = appearance?.variables ?? {};
1105
+ const primaryColor = vars.colorPrimary;
1106
+ const cardBg = vars.colorBackground ?? "rgba(22,27,45,0.92)";
1107
+ const textColor = vars.colorText ?? "rgba(255,255,255,0.9)";
1108
+ const mutedColor = vars.colorTextMuted ?? "#475569";
1109
+ let appConfig = null;
1110
+ try {
1111
+ appConfig = useVaultixContext().appConfig;
1112
+ } catch {
1113
+ }
1114
+ const enabledProviders = appConfig?.providers ?? ["google", "github", "meta", "linkedin", "x", "threads"];
1115
+ const enabledMethods = appConfig?.methods ?? ["password", "magic_link", "passkey"];
1116
+ const hasPassword = enabledMethods.includes("password");
986
1117
  const [step, setStep] = (0, import_react4.useState)("email");
987
1118
  const [email, setEmail] = (0, import_react4.useState)("");
988
1119
  const [password, setPassword] = (0, import_react4.useState)("");
@@ -1001,10 +1132,12 @@ function SignUp({
1001
1132
  url.searchParams.set("__vaultix_handshake", handshakeToken);
1002
1133
  window.location.href = url.toString();
1003
1134
  }
1004
- function handleGoogleSignUp() {
1135
+ function oauthRedirect(provider) {
1005
1136
  const target = resolveAfterSignUpUrl(redirectUrl);
1137
+ const pk = resolvePk2();
1006
1138
  const params = new URLSearchParams({ redirect_url: target });
1007
- window.location.href = `${apiOrigin}/api/v1/auth/oauth/google?${params}`;
1139
+ if (pk) params.set("pk", pk);
1140
+ window.location.href = `${apiOrigin}/api/v1/auth/oauth/${provider}?${params}`;
1008
1141
  }
1009
1142
  async function handleEmailPassword(e) {
1010
1143
  e.preventDefault();
@@ -1075,48 +1208,61 @@ function SignUp({
1075
1208
  "w-full max-w-sm mx-auto rounded-2xl border border-white/8 shadow-2xl backdrop-blur-[16px]",
1076
1209
  className
1077
1210
  ),
1078
- style: { background: "rgba(22,27,45,0.92)" },
1211
+ style: { background: cardBg },
1079
1212
  children: [
1080
1213
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "px-8 pt-8 pb-6 text-center", children: [
1081
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "inline-flex items-center justify-center w-10 h-10 rounded-xl bg-gradient-to-br from-emerald-600 to-teal-600 shadow-lg shadow-emerald-500/30 mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) }),
1082
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "text-xl font-semibold text-white/90", children: step === "verify" ? "Check your email" : "Create an account" }),
1083
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-[#475569] mt-1", children: step === "verify" ? `We sent a code to ${email}` : "Start your free trial today" })
1214
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1215
+ "div",
1216
+ {
1217
+ className: "inline-flex items-center justify-center w-10 h-10 rounded-xl shadow-lg mb-4",
1218
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}4d` } : { background: "linear-gradient(to bottom right, #059669, #0d9488)", boxShadow: "0 10px 15px -3px rgba(5,150,105,0.3)" },
1219
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {})
1220
+ }
1221
+ ),
1222
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "text-xl font-semibold", style: { color: textColor }, children: step === "verify" ? "Check your email" : "Create an account" }),
1223
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm mt-1", style: { color: mutedColor }, children: step === "verify" ? `We sent a code to ${email}` : "Start your free trial today" })
1084
1224
  ] }),
1085
1225
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
1086
1226
  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 }) }),
1087
1227
  step === "email" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-3", children: [
1088
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleButton2, { onClick: handleGoogleSignUp }),
1089
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Divider2, {}),
1090
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
1228
+ enabledProviders.includes("google") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleIcon2, {}), label: "Continue with Google", onClick: () => oauthRedirect("google") }),
1229
+ enabledProviders.includes("github") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GitHubIcon2, {}), label: "Continue with GitHub", onClick: () => oauthRedirect("github") }),
1230
+ enabledProviders.includes("meta") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MetaIcon2, {}), label: "Continue with Facebook", onClick: () => oauthRedirect("meta") }),
1231
+ enabledProviders.includes("linkedin") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LinkedInIcon2, {}), label: "Continue with LinkedIn", onClick: () => oauthRedirect("linkedin") }),
1232
+ enabledProviders.includes("x") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(XIcon2, {}), label: "Continue with X", onClick: () => oauthRedirect("x") }),
1233
+ hasPassword && enabledProviders.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Divider2, { mutedColor }),
1234
+ hasPassword && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
1091
1235
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1092
- SignUpInput,
1236
+ Input2,
1093
1237
  {
1094
1238
  type: "email",
1095
1239
  placeholder: "you@company.com",
1096
1240
  value: email,
1097
1241
  onChange: setEmail,
1098
1242
  autoFocus: true,
1099
- required: true
1243
+ required: true,
1244
+ primaryColor
1100
1245
  }
1101
1246
  ),
1102
1247
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1103
- SignUpInput,
1248
+ Input2,
1104
1249
  {
1105
1250
  type: "password",
1106
1251
  placeholder: "Create a password",
1107
1252
  value: password,
1108
1253
  onChange: setPassword,
1109
1254
  required: true,
1110
- minLength: 8
1255
+ minLength: 8,
1256
+ primaryColor
1111
1257
  }
1112
1258
  ),
1113
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PasswordStrength2, { password }),
1114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignUpPrimaryButton, { loading, children: "Create account" })
1259
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PasswordStrength2, { password, primaryColor }),
1260
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrimaryButton2, { loading, primaryColor, children: "Create account" })
1115
1261
  ] })
1116
1262
  ] }),
1117
1263
  step === "verify" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleVerification, className: "space-y-3", children: [
1118
1264
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1119
- SignUpInput,
1265
+ Input2,
1120
1266
  {
1121
1267
  type: "text",
1122
1268
  inputMode: "numeric",
@@ -1127,16 +1273,18 @@ function SignUp({
1127
1273
  onChange: setVerificationCode,
1128
1274
  autoFocus: true,
1129
1275
  required: true,
1130
- className: "text-center tracking-[0.4em] text-lg"
1276
+ className: "text-center tracking-[0.4em] text-lg",
1277
+ primaryColor
1131
1278
  }
1132
1279
  ),
1133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignUpPrimaryButton, { loading, children: "Verify email" }),
1280
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrimaryButton2, { loading, primaryColor, children: "Verify email" }),
1134
1281
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1135
1282
  "button",
1136
1283
  {
1137
1284
  type: "button",
1138
1285
  onClick: resendCode,
1139
- className: "w-full text-xs text-[#475569] hover:text-white/70 transition-colors py-1",
1286
+ className: "w-full text-xs transition-colors py-1 hover:opacity-80",
1287
+ style: { color: mutedColor },
1140
1288
  children: "Resend code"
1141
1289
  }
1142
1290
  )
@@ -1146,7 +1294,7 @@ function SignUp({
1146
1294
  }
1147
1295
  );
1148
1296
  }
1149
- function SignUpInput({ onChange, className, ...props }) {
1297
+ function Input2({ onChange, className, primaryColor, ...props }) {
1150
1298
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1151
1299
  "input",
1152
1300
  {
@@ -1155,34 +1303,47 @@ function SignUpInput({ onChange, className, ...props }) {
1155
1303
  className: (0, import_clsx2.clsx)(
1156
1304
  "w-full bg-white/5 border border-white/8 rounded-xl px-4 py-2.5",
1157
1305
  "text-sm text-white/90 placeholder:text-[#475569]",
1158
- "focus:outline-none focus:border-emerald-500/60 transition-colors",
1306
+ "focus:outline-none transition-colors",
1307
+ !primaryColor && "focus:border-emerald-500/60",
1159
1308
  className
1160
- )
1309
+ ),
1310
+ onFocus: (e) => {
1311
+ if (primaryColor) e.currentTarget.style.borderColor = `${primaryColor}99`;
1312
+ props.onFocus?.(e);
1313
+ },
1314
+ onBlur: (e) => {
1315
+ if (primaryColor) e.currentTarget.style.borderColor = "";
1316
+ props.onBlur?.(e);
1317
+ }
1161
1318
  }
1162
1319
  );
1163
1320
  }
1164
- function SignUpPrimaryButton({
1321
+ function PrimaryButton2({
1165
1322
  children,
1166
- loading
1323
+ loading,
1324
+ primaryColor
1167
1325
  }) {
1168
1326
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1169
1327
  "button",
1170
1328
  {
1171
1329
  type: "submit",
1172
1330
  disabled: loading,
1331
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}33` } : void 0,
1173
1332
  className: (0, import_clsx2.clsx)(
1174
1333
  "w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl",
1175
- "text-sm font-semibold text-white",
1176
- "bg-gradient-to-r from-emerald-600 to-teal-600",
1177
- "hover:from-emerald-500 hover:to-teal-500",
1178
- "shadow-lg shadow-emerald-500/20 transition-all duration-150",
1179
- "disabled:opacity-60 disabled:cursor-not-allowed"
1334
+ "text-sm font-semibold text-white transition-all duration-150",
1335
+ "disabled:opacity-60 disabled:cursor-not-allowed",
1336
+ !primaryColor && "bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-500 hover:to-teal-500 shadow-lg shadow-emerald-500/20"
1180
1337
  ),
1181
1338
  children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner2, {}) : children
1182
1339
  }
1183
1340
  );
1184
1341
  }
1185
- function GoogleButton2({ onClick }) {
1342
+ function OAuthButton2({
1343
+ icon,
1344
+ label,
1345
+ onClick
1346
+ }) {
1186
1347
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1187
1348
  "button",
1188
1349
  {
@@ -1196,20 +1357,20 @@ function GoogleButton2({ onClick }) {
1196
1357
  "transition-all duration-150"
1197
1358
  ),
1198
1359
  children: [
1199
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleIcon2, {}),
1200
- "Continue with Google"
1360
+ icon,
1361
+ label
1201
1362
  ]
1202
1363
  }
1203
1364
  );
1204
1365
  }
1205
- function Divider2() {
1366
+ function Divider2({ mutedColor }) {
1206
1367
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-3", children: [
1207
1368
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-white/8" }),
1208
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] text-[#475569] uppercase tracking-wider", children: "or" }),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] uppercase tracking-wider", style: { color: mutedColor ?? "#475569" }, children: "or" }),
1209
1370
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-white/8" })
1210
1371
  ] });
1211
1372
  }
1212
- function PasswordStrength2({ password }) {
1373
+ function PasswordStrength2({ password, primaryColor }) {
1213
1374
  const score = (() => {
1214
1375
  if (password.length === 0) return 0;
1215
1376
  let s = 0;
@@ -1221,15 +1382,17 @@ function PasswordStrength2({ password }) {
1221
1382
  })();
1222
1383
  if (password.length === 0) return null;
1223
1384
  const labels = ["", "Weak", "Fair", "Good", "Strong"];
1224
- const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
1385
+ const tailwindColors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
1225
1386
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-1", children: [
1226
1387
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex gap-1", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1227
1388
  "div",
1228
1389
  {
1229
1390
  className: (0, import_clsx2.clsx)(
1230
1391
  "flex-1 h-0.5 rounded-full transition-all duration-300",
1231
- i <= score ? colors[score] : "bg-white/10"
1232
- )
1392
+ i <= score && !primaryColor ? tailwindColors[score] : void 0,
1393
+ i > score || !primaryColor && i <= score ? void 0 : void 0
1394
+ ),
1395
+ style: i <= score && primaryColor ? { background: score >= 4 ? primaryColor : void 0 } : { background: i <= score ? void 0 : "rgba(255,255,255,0.1)" }
1233
1396
  },
1234
1397
  i
1235
1398
  )) }),
@@ -1253,6 +1416,18 @@ function GoogleIcon2() {
1253
1416
  /* @__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" })
1254
1417
  ] });
1255
1418
  }
1419
+ function MetaIcon2() {
1420
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "#1877F2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" }) });
1421
+ }
1422
+ function LinkedInIcon2() {
1423
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "#0A66C2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.063 2.063 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" }) });
1424
+ }
1425
+ function GitHubIcon2() {
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2z" }) });
1427
+ }
1428
+ function XIcon2() {
1429
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.737-8.835L1.254 2.25H8.08l4.253 5.622 5.911-5.622zm-1.161 17.52h1.833L7.084 4.126H5.117z" }) });
1430
+ }
1256
1431
 
1257
1432
  // src/components/SignedIn.tsx
1258
1433
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -2039,6 +2214,7 @@ function clearStoredToken() {
2039
2214
  getStoredToken,
2040
2215
  useAuth,
2041
2216
  useOrganization,
2217
+ usePlatformConnect,
2042
2218
  useSession,
2043
2219
  useUser,
2044
2220
  useVaultix