@vaultix.ai/react 0.3.3 → 0.3.4

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
@@ -304,6 +305,44 @@ function useOrganization() {
304
305
  const { organization, isLoaded } = useVaultixContext();
305
306
  return { organization, isLoaded };
306
307
  }
308
+ function usePlatformConnect(provider, defaultOptions) {
309
+ const { connectPlatform } = useVaultixContext();
310
+ const [connectedAccount, setConnectedAccount] = (0, import_react2.useState)(null);
311
+ const connect = (0, import_react2.useCallback)(
312
+ (overrides) => {
313
+ connectPlatform(provider, { ...defaultOptions, ...overrides });
314
+ },
315
+ [connectPlatform, provider, defaultOptions]
316
+ );
317
+ (0, import_react2.useEffect)(() => {
318
+ if (typeof window === "undefined") return;
319
+ const params = new URLSearchParams(window.location.search);
320
+ const connectToken = params.get("__vaultix_connect");
321
+ const returnedProvider = params.get("provider");
322
+ if (!connectToken || returnedProvider !== provider) return;
323
+ try {
324
+ const segment = connectToken.split(".")[1];
325
+ if (!segment) return;
326
+ const b64 = segment.replace(/-/g, "+").replace(/_/g, "/");
327
+ const payload = JSON.parse(atob(b64));
328
+ const result = {
329
+ provider: returnedProvider,
330
+ raw: payload,
331
+ ...typeof payload["platform_user_id"] === "string" && { platformUserId: payload["platform_user_id"] },
332
+ ...typeof payload["username"] === "string" && { username: payload["username"] },
333
+ ...typeof payload["access_token"] === "string" && { accessToken: payload["access_token"] },
334
+ ...typeof payload["scope"] === "string" && { scope: payload["scope"] }
335
+ };
336
+ setConnectedAccount(result);
337
+ const clean = new URL(window.location.href);
338
+ clean.searchParams.delete("__vaultix_connect");
339
+ clean.searchParams.delete("provider");
340
+ window.history.replaceState({}, "", clean.toString());
341
+ } catch {
342
+ }
343
+ }, [provider]);
344
+ return { connect, connectedAccount };
345
+ }
307
346
  function useAuth() {
308
347
  const { user, session, isLoaded, isSignedIn, signOut } = useVaultixContext();
309
348
  const getToken = (0, import_react2.useCallback)(async () => {
@@ -365,9 +404,15 @@ function SignIn({
365
404
  onSuccess,
366
405
  onError,
367
406
  apiOrigin: apiOriginProp,
368
- className
407
+ className,
408
+ appearance
369
409
  }) {
370
410
  const apiOrigin = resolveApiOrigin2(apiOriginProp);
411
+ const vars = appearance?.variables ?? {};
412
+ const primaryColor = vars.colorPrimary;
413
+ const cardBg = vars.colorBackground ?? "rgba(22,27,45,0.92)";
414
+ const textColor = vars.colorText ?? "rgba(255,255,255,0.9)";
415
+ const mutedColor = vars.colorTextMuted ?? "#475569";
371
416
  const [step, setStep] = (0, import_react3.useState)("email");
372
417
  const [email, setEmail] = (0, import_react3.useState)("");
373
418
  const [password, setPassword] = (0, import_react3.useState)("");
@@ -632,12 +677,19 @@ function SignIn({
632
677
  "backdrop-blur-[16px]",
633
678
  className
634
679
  ),
635
- style: { background: "rgba(22,27,45,0.92)" },
680
+ style: { background: cardBg },
636
681
  children: [
637
682
  /* @__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] })
683
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
684
+ "div",
685
+ {
686
+ className: "inline-flex items-center justify-center w-10 h-10 rounded-xl shadow-lg mb-4",
687
+ 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)" },
688
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LockIcon, {})
689
+ }
690
+ ),
691
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-xl font-semibold", style: { color: textColor }, children: title[step] }),
692
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm mt-1", style: { color: mutedColor }, children: subtitle[step] })
641
693
  ] }),
642
694
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
643
695
  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 }) }),
@@ -648,7 +700,7 @@ function SignIn({
648
700
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetaButton, { onClick: handleMetaSignIn }),
649
701
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LinkedInButton, { onClick: handleLinkedInSignIn }),
650
702
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XButton, { onClick: handleXSignIn }),
651
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Divider, {}),
703
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Divider, { mutedColor }),
652
704
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleEmailSubmit, className: "space-y-3", children: [
653
705
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
654
706
  Input,
@@ -658,10 +710,11 @@ function SignIn({
658
710
  value: email,
659
711
  onChange: setEmail,
660
712
  autoFocus: true,
661
- required: true
713
+ required: true,
714
+ primaryColor
662
715
  }
663
716
  ),
664
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
717
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Continue" })
665
718
  ] })
666
719
  ] }),
667
720
  step === "password" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handlePasswordSubmit, className: "space-y-3", children: [
@@ -673,42 +726,50 @@ function SignIn({
673
726
  value: password,
674
727
  onChange: setPassword,
675
728
  autoFocus: true,
676
- required: true
729
+ required: true,
730
+ primaryColor
677
731
  }
678
732
  ),
679
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Sign in" }),
733
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Sign in" }),
680
734
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
681
735
  /* @__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" }),
736
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px]", style: { color: mutedColor }, children: "or" }),
683
737
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
684
738
  ] }),
685
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, children: "\u2709 Email me a sign-in link" }),
739
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, mutedColor, children: "\u2709 Email me a sign-in link" }),
686
740
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
687
741
  setStep("forgot");
688
742
  setError(null);
689
- }, children: "Forgot password?" }),
690
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), children: "\u2190 Back" })
743
+ }, mutedColor, children: "Forgot password?" }),
744
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), mutedColor, children: "\u2190 Back" })
691
745
  ] }),
692
746
  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: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
748
+ "div",
749
+ {
750
+ className: "w-14 h-14 rounded-2xl flex items-center justify-center mx-auto border",
751
+ style: primaryColor ? { background: `${primaryColor}26`, borderColor: `${primaryColor}4d` } : { background: "rgba(168,85,247,0.15)", borderColor: "rgba(168,85,247,0.3)" },
752
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EnvelopeIcon, { color: primaryColor ?? "#a78bfa" })
753
+ }
754
+ ),
755
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "text-sm leading-relaxed", style: { color: mutedColor }, children: [
695
756
  "The link expires in ",
696
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-white/80 font-medium", children: "15 minutes" }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor }, className: "font-medium", children: "15 minutes" }),
697
758
  " and can only be used once."
698
759
  ] }),
699
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, children: "Resend link" }),
760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: handleMagicLinkRequest, mutedColor, children: "Resend link" }),
700
761
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
701
762
  setStep("password");
702
763
  setError(null);
703
- }, children: "Use password instead" })
764
+ }, mutedColor, children: "Use password instead" })
704
765
  ] }),
705
766
  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: [
767
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(PrimaryButton, { loading, onClick: handlePasskeySignIn, primaryColor, children: [
707
768
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FingerprintIcon, {}),
708
769
  "Authenticate with passkey"
709
770
  ] }),
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" })
771
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), mutedColor, children: "Use password instead" }),
772
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("email"), mutedColor, children: "\u2190 Back" })
712
773
  ] }),
713
774
  step === "totp" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleTotpSubmit, className: "space-y-3", children: [
714
775
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -723,11 +784,12 @@ function SignIn({
723
784
  onChange: setTotp,
724
785
  autoFocus: true,
725
786
  required: true,
726
- className: "text-center tracking-[0.4em] text-lg"
787
+ className: "text-center tracking-[0.4em] text-lg",
788
+ primaryColor
727
789
  }
728
790
  ),
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" })
791
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Verify" }),
792
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => setStep("password"), mutedColor, children: "\u2190 Back" })
731
793
  ] }),
732
794
  step === "forgot" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotSubmit, className: "space-y-3", children: [
733
795
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -738,14 +800,15 @@ function SignIn({
738
800
  value: email,
739
801
  onChange: setEmail,
740
802
  autoFocus: true,
741
- required: true
803
+ required: true,
804
+ primaryColor
742
805
  }
743
806
  ),
744
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Send reset code" }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Send reset code" }),
745
808
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GhostButton, { onClick: () => {
746
809
  setStep("password");
747
810
  setError(null);
748
- }, children: "\u2190 Back" })
811
+ }, mutedColor, children: "\u2190 Back" })
749
812
  ] }),
750
813
  step === "forgot-verify" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleForgotVerifySubmit, className: "space-y-3", children: [
751
814
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -760,10 +823,11 @@ function SignIn({
760
823
  onChange: setForgotCode,
761
824
  autoFocus: true,
762
825
  required: true,
763
- className: "text-center tracking-[0.4em] text-lg"
826
+ className: "text-center tracking-[0.4em] text-lg",
827
+ primaryColor
764
828
  }
765
829
  ),
766
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Continue" })
830
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Continue" })
767
831
  ] }),
768
832
  step === "forgot-reset" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleResetPasswordSubmit, className: "space-y-3", children: [
769
833
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -775,18 +839,19 @@ function SignIn({
775
839
  onChange: setNewPassword,
776
840
  autoFocus: true,
777
841
  required: true,
778
- minLength: 8
842
+ minLength: 8,
843
+ primaryColor
779
844
  }
780
845
  ),
781
846
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PasswordStrength, { password: newPassword }),
782
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, children: "Reset password" })
847
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PrimaryButton, { loading, primaryColor, children: "Reset password" })
783
848
  ] })
784
849
  ] })
785
850
  ]
786
851
  }
787
852
  );
788
853
  }
789
- function Input({ onChange, className, ...props }) {
854
+ function Input({ onChange, className, primaryColor, ...props }) {
790
855
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
791
856
  "input",
792
857
  {
@@ -795,39 +860,48 @@ function Input({ onChange, className, ...props }) {
795
860
  className: (0, import_clsx.clsx)(
796
861
  "w-full bg-white/5 border border-white/8 rounded-xl px-4 py-2.5",
797
862
  "text-sm text-white/90 placeholder:text-[#475569]",
798
- "focus:outline-none focus:border-purple-500/60 transition-colors",
863
+ "focus:outline-none transition-colors",
864
+ !primaryColor && "focus:border-purple-500/60",
799
865
  className
800
- )
866
+ ),
867
+ style: primaryColor ? { "--vx-focus": primaryColor } : void 0,
868
+ onFocus: (e) => {
869
+ if (primaryColor) e.currentTarget.style.borderColor = `${primaryColor}99`;
870
+ props.onFocus?.(e);
871
+ },
872
+ onBlur: (e) => {
873
+ if (primaryColor) e.currentTarget.style.borderColor = "";
874
+ props.onBlur?.(e);
875
+ }
801
876
  }
802
877
  );
803
878
  }
804
- function PrimaryButton({ children, loading, onClick }) {
879
+ function PrimaryButton({ children, loading, onClick, primaryColor }) {
805
880
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
806
881
  "button",
807
882
  {
808
883
  type: onClick ? "button" : "submit",
809
884
  onClick,
810
885
  disabled: loading,
886
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}33` } : void 0,
811
887
  className: (0, import_clsx.clsx)(
812
888
  "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"
889
+ "text-sm font-semibold text-white transition-all duration-150",
890
+ "disabled:opacity-60 disabled:cursor-not-allowed",
891
+ !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
892
  ),
820
893
  children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : children
821
894
  }
822
895
  );
823
896
  }
824
- function GhostButton({ children, onClick }) {
897
+ function GhostButton({ children, onClick, mutedColor }) {
825
898
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
826
899
  "button",
827
900
  {
828
901
  type: "button",
829
902
  onClick,
830
- className: "w-full text-xs text-[#475569] hover:text-white/70 transition-colors py-1",
903
+ className: "w-full text-xs transition-colors py-1 hover:opacity-80",
904
+ style: { color: mutedColor ?? "#475569" },
831
905
  children
832
906
  }
833
907
  );
@@ -871,10 +945,10 @@ function GitHubButton({ onClick }) {
871
945
  function XButton({ onClick }) {
872
946
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(OAuthButton, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XIcon, {}), label: "Continue with X", onClick });
873
947
  }
874
- function Divider() {
948
+ function Divider({ mutedColor }) {
875
949
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3", children: [
876
950
  /* @__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" }),
951
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] uppercase tracking-wider", style: { color: mutedColor ?? "#475569" }, children: "or" }),
878
952
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 h-px bg-white/8" })
879
953
  ] });
880
954
  }
@@ -944,8 +1018,8 @@ function GitHubIcon() {
944
1018
  function XIcon() {
945
1019
  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
1020
  }
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: [
1021
+ function EnvelopeIcon({ color = "#a78bfa" }) {
1022
+ 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
1023
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
950
1024
  /* @__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
1025
  ] });
@@ -963,6 +1037,13 @@ function resolveApiOrigin3(prop) {
963
1037
  }
964
1038
  return "";
965
1039
  }
1040
+ function resolvePk2() {
1041
+ if (typeof document !== "undefined") {
1042
+ const el = document.querySelector("[data-vaultix-pk]");
1043
+ if (el) return el.getAttribute("data-vaultix-pk") ?? "";
1044
+ }
1045
+ return "";
1046
+ }
966
1047
  function resolveAfterSignUpUrl(redirectUrlProp) {
967
1048
  if (redirectUrlProp) return redirectUrlProp;
968
1049
  if (typeof document !== "undefined") {
@@ -980,9 +1061,15 @@ function SignUp({
980
1061
  onSuccess,
981
1062
  onError,
982
1063
  apiOrigin: apiOriginProp,
983
- className
1064
+ className,
1065
+ appearance
984
1066
  }) {
985
1067
  const apiOrigin = resolveApiOrigin3(apiOriginProp);
1068
+ const vars = appearance?.variables ?? {};
1069
+ const primaryColor = vars.colorPrimary;
1070
+ const cardBg = vars.colorBackground ?? "rgba(22,27,45,0.92)";
1071
+ const textColor = vars.colorText ?? "rgba(255,255,255,0.9)";
1072
+ const mutedColor = vars.colorTextMuted ?? "#475569";
986
1073
  const [step, setStep] = (0, import_react4.useState)("email");
987
1074
  const [email, setEmail] = (0, import_react4.useState)("");
988
1075
  const [password, setPassword] = (0, import_react4.useState)("");
@@ -1001,10 +1088,12 @@ function SignUp({
1001
1088
  url.searchParams.set("__vaultix_handshake", handshakeToken);
1002
1089
  window.location.href = url.toString();
1003
1090
  }
1004
- function handleGoogleSignUp() {
1091
+ function oauthRedirect(provider) {
1005
1092
  const target = resolveAfterSignUpUrl(redirectUrl);
1093
+ const pk = resolvePk2();
1006
1094
  const params = new URLSearchParams({ redirect_url: target });
1007
- window.location.href = `${apiOrigin}/api/v1/auth/oauth/google?${params}`;
1095
+ if (pk) params.set("pk", pk);
1096
+ window.location.href = `${apiOrigin}/api/v1/auth/oauth/${provider}?${params}`;
1008
1097
  }
1009
1098
  async function handleEmailPassword(e) {
1010
1099
  e.preventDefault();
@@ -1075,48 +1164,61 @@ function SignUp({
1075
1164
  "w-full max-w-sm mx-auto rounded-2xl border border-white/8 shadow-2xl backdrop-blur-[16px]",
1076
1165
  className
1077
1166
  ),
1078
- style: { background: "rgba(22,27,45,0.92)" },
1167
+ style: { background: cardBg },
1079
1168
  children: [
1080
1169
  /* @__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" })
1170
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1171
+ "div",
1172
+ {
1173
+ className: "inline-flex items-center justify-center w-10 h-10 rounded-xl shadow-lg mb-4",
1174
+ 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)" },
1175
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {})
1176
+ }
1177
+ ),
1178
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "text-xl font-semibold", style: { color: textColor }, children: step === "verify" ? "Check your email" : "Create an account" }),
1179
+ /* @__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
1180
  ] }),
1085
1181
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "px-8 pb-8 space-y-4", children: [
1086
1182
  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
1183
  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, {}),
1184
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleIcon2, {}), label: "Continue with Google", onClick: () => oauthRedirect("google") }),
1185
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GitHubIcon2, {}), label: "Continue with GitHub", onClick: () => oauthRedirect("github") }),
1186
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MetaIcon2, {}), label: "Continue with Facebook", onClick: () => oauthRedirect("meta") }),
1187
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LinkedInIcon2, {}), label: "Continue with LinkedIn", onClick: () => oauthRedirect("linkedin") }),
1188
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OAuthButton2, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(XIcon2, {}), label: "Continue with X", onClick: () => oauthRedirect("x") }),
1189
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Divider2, { mutedColor }),
1090
1190
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleEmailPassword, className: "space-y-3", children: [
1091
1191
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1092
- SignUpInput,
1192
+ Input2,
1093
1193
  {
1094
1194
  type: "email",
1095
1195
  placeholder: "you@company.com",
1096
1196
  value: email,
1097
1197
  onChange: setEmail,
1098
1198
  autoFocus: true,
1099
- required: true
1199
+ required: true,
1200
+ primaryColor
1100
1201
  }
1101
1202
  ),
1102
1203
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1103
- SignUpInput,
1204
+ Input2,
1104
1205
  {
1105
1206
  type: "password",
1106
1207
  placeholder: "Create a password",
1107
1208
  value: password,
1108
1209
  onChange: setPassword,
1109
1210
  required: true,
1110
- minLength: 8
1211
+ minLength: 8,
1212
+ primaryColor
1111
1213
  }
1112
1214
  ),
1113
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PasswordStrength2, { password }),
1114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignUpPrimaryButton, { loading, children: "Create account" })
1215
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PasswordStrength2, { password, primaryColor }),
1216
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrimaryButton2, { loading, primaryColor, children: "Create account" })
1115
1217
  ] })
1116
1218
  ] }),
1117
1219
  step === "verify" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleVerification, className: "space-y-3", children: [
1118
1220
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1119
- SignUpInput,
1221
+ Input2,
1120
1222
  {
1121
1223
  type: "text",
1122
1224
  inputMode: "numeric",
@@ -1127,16 +1229,18 @@ function SignUp({
1127
1229
  onChange: setVerificationCode,
1128
1230
  autoFocus: true,
1129
1231
  required: true,
1130
- className: "text-center tracking-[0.4em] text-lg"
1232
+ className: "text-center tracking-[0.4em] text-lg",
1233
+ primaryColor
1131
1234
  }
1132
1235
  ),
1133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignUpPrimaryButton, { loading, children: "Verify email" }),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PrimaryButton2, { loading, primaryColor, children: "Verify email" }),
1134
1237
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1135
1238
  "button",
1136
1239
  {
1137
1240
  type: "button",
1138
1241
  onClick: resendCode,
1139
- className: "w-full text-xs text-[#475569] hover:text-white/70 transition-colors py-1",
1242
+ className: "w-full text-xs transition-colors py-1 hover:opacity-80",
1243
+ style: { color: mutedColor },
1140
1244
  children: "Resend code"
1141
1245
  }
1142
1246
  )
@@ -1146,7 +1250,7 @@ function SignUp({
1146
1250
  }
1147
1251
  );
1148
1252
  }
1149
- function SignUpInput({ onChange, className, ...props }) {
1253
+ function Input2({ onChange, className, primaryColor, ...props }) {
1150
1254
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1151
1255
  "input",
1152
1256
  {
@@ -1155,34 +1259,47 @@ function SignUpInput({ onChange, className, ...props }) {
1155
1259
  className: (0, import_clsx2.clsx)(
1156
1260
  "w-full bg-white/5 border border-white/8 rounded-xl px-4 py-2.5",
1157
1261
  "text-sm text-white/90 placeholder:text-[#475569]",
1158
- "focus:outline-none focus:border-emerald-500/60 transition-colors",
1262
+ "focus:outline-none transition-colors",
1263
+ !primaryColor && "focus:border-emerald-500/60",
1159
1264
  className
1160
- )
1265
+ ),
1266
+ onFocus: (e) => {
1267
+ if (primaryColor) e.currentTarget.style.borderColor = `${primaryColor}99`;
1268
+ props.onFocus?.(e);
1269
+ },
1270
+ onBlur: (e) => {
1271
+ if (primaryColor) e.currentTarget.style.borderColor = "";
1272
+ props.onBlur?.(e);
1273
+ }
1161
1274
  }
1162
1275
  );
1163
1276
  }
1164
- function SignUpPrimaryButton({
1277
+ function PrimaryButton2({
1165
1278
  children,
1166
- loading
1279
+ loading,
1280
+ primaryColor
1167
1281
  }) {
1168
1282
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1169
1283
  "button",
1170
1284
  {
1171
1285
  type: "submit",
1172
1286
  disabled: loading,
1287
+ style: primaryColor ? { background: primaryColor, boxShadow: `0 10px 15px -3px ${primaryColor}33` } : void 0,
1173
1288
  className: (0, import_clsx2.clsx)(
1174
1289
  "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"
1290
+ "text-sm font-semibold text-white transition-all duration-150",
1291
+ "disabled:opacity-60 disabled:cursor-not-allowed",
1292
+ !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
1293
  ),
1181
1294
  children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner2, {}) : children
1182
1295
  }
1183
1296
  );
1184
1297
  }
1185
- function GoogleButton2({ onClick }) {
1298
+ function OAuthButton2({
1299
+ icon,
1300
+ label,
1301
+ onClick
1302
+ }) {
1186
1303
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1187
1304
  "button",
1188
1305
  {
@@ -1196,20 +1313,20 @@ function GoogleButton2({ onClick }) {
1196
1313
  "transition-all duration-150"
1197
1314
  ),
1198
1315
  children: [
1199
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleIcon2, {}),
1200
- "Continue with Google"
1316
+ icon,
1317
+ label
1201
1318
  ]
1202
1319
  }
1203
1320
  );
1204
1321
  }
1205
- function Divider2() {
1322
+ function Divider2({ mutedColor }) {
1206
1323
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-3", children: [
1207
1324
  /* @__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" }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] uppercase tracking-wider", style: { color: mutedColor ?? "#475569" }, children: "or" }),
1209
1326
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-white/8" })
1210
1327
  ] });
1211
1328
  }
1212
- function PasswordStrength2({ password }) {
1329
+ function PasswordStrength2({ password, primaryColor }) {
1213
1330
  const score = (() => {
1214
1331
  if (password.length === 0) return 0;
1215
1332
  let s = 0;
@@ -1221,15 +1338,17 @@ function PasswordStrength2({ password }) {
1221
1338
  })();
1222
1339
  if (password.length === 0) return null;
1223
1340
  const labels = ["", "Weak", "Fair", "Good", "Strong"];
1224
- const colors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
1341
+ const tailwindColors = ["", "bg-red-500", "bg-amber-400", "bg-blue-400", "bg-emerald-400"];
1225
1342
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-1", children: [
1226
1343
  /* @__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
1344
  "div",
1228
1345
  {
1229
1346
  className: (0, import_clsx2.clsx)(
1230
1347
  "flex-1 h-0.5 rounded-full transition-all duration-300",
1231
- i <= score ? colors[score] : "bg-white/10"
1232
- )
1348
+ i <= score && !primaryColor ? tailwindColors[score] : void 0,
1349
+ i > score || !primaryColor && i <= score ? void 0 : void 0
1350
+ ),
1351
+ style: i <= score && primaryColor ? { background: score >= 4 ? primaryColor : void 0 } : { background: i <= score ? void 0 : "rgba(255,255,255,0.1)" }
1233
1352
  },
1234
1353
  i
1235
1354
  )) }),
@@ -1253,6 +1372,18 @@ function GoogleIcon2() {
1253
1372
  /* @__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
1373
  ] });
1255
1374
  }
1375
+ function MetaIcon2() {
1376
+ 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" }) });
1377
+ }
1378
+ function LinkedInIcon2() {
1379
+ 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" }) });
1380
+ }
1381
+ function GitHubIcon2() {
1382
+ 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" }) });
1383
+ }
1384
+ function XIcon2() {
1385
+ 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" }) });
1386
+ }
1256
1387
 
1257
1388
  // src/components/SignedIn.tsx
1258
1389
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -2039,6 +2170,7 @@ function clearStoredToken() {
2039
2170
  getStoredToken,
2040
2171
  useAuth,
2041
2172
  useOrganization,
2173
+ usePlatformConnect,
2042
2174
  useSession,
2043
2175
  useUser,
2044
2176
  useVaultix