@base316/react 0.7.0 → 0.8.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.cjs CHANGED
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  VerifyEmail: () => VerifyEmail,
73
73
  componentsRequiring: () => componentsRequiring,
74
74
  describeComponent: () => describeComponent,
75
+ useAddons: () => useAddons,
75
76
  useBase316: () => useBase316,
76
77
  useCollection: () => useCollection,
77
78
  usePaymentLink: () => usePaymentLink,
@@ -235,7 +236,7 @@ var STYLESHEET = `
235
236
  }
236
237
 
237
238
  /* The recommended plan. Lifted rather than merely tinted: on a pricing table
238
- the eye needs one obvious default, and colour alone does not survive being
239
+ the eye needs one obvious default, and color alone does not survive being
239
240
  viewed in greyscale or by someone who cannot distinguish the accent. */
240
241
  .b316-plan-featured {
241
242
  border-color: var(--b316-color-primary);
@@ -622,7 +623,7 @@ var STYLESHEET_EXTRA = `
622
623
  .b316-mfa-uri { font-size: 0.9em; }
623
624
  .b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
624
625
  .b316-mfa-code-list code { user-select: all; }
625
- /* The enrolment choices: whole-width buttons with their explanation inside,
626
+ /* The enrollment choices: whole-width buttons with their explanation inside,
626
627
  so the explanation is part of what a screen reader announces. */
627
628
  .b316-mfa-methods { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }
628
629
  .b316-mfa-method { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; }
@@ -753,7 +754,7 @@ function Base316Provider({
753
754
  const [internalToken, setInternalToken] = (0, import_react.useState)(null);
754
755
  const [session, setSession] = (0, import_react.useState)(null);
755
756
  const [branding, setBranding] = (0, import_react.useState)(null);
756
- const [loading, setLoading] = (0, import_react.useState)(true);
757
+ const [loading2, setLoading] = (0, import_react.useState)(true);
757
758
  const token = controlled ? controlledToken : internalToken;
758
759
  (0, import_react.useEffect)(() => {
759
760
  if (controlled) {
@@ -815,8 +816,8 @@ function Base316Provider({
815
816
  setSession(null);
816
817
  }, [client, token, setToken]);
817
818
  const value = (0, import_react.useMemo)(
818
- () => ({ client, branding, token, setToken, session, loading, refresh, signOut }),
819
- [client, branding, token, setToken, session, loading, refresh, signOut]
819
+ () => ({ client, branding, token, setToken, session, loading: loading2, refresh, signOut }),
820
+ [client, branding, token, setToken, session, loading2, refresh, signOut]
820
821
  );
821
822
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Base316Context.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
822
823
  "div",
@@ -825,7 +826,7 @@ function Base316Provider({
825
826
  style: appearanceToStyle({
826
827
  // Whatever was set in the sign-in designer arrives here, so a
827
828
  // customer styles their login once on Base316 and the embedded
828
- // components follow — rather than configuring the same colours
829
+ // components follow — rather than configuring the same colors
829
830
  // twice and watching them drift apart.
830
831
  //
831
832
  // An explicit `appearance` still wins, because a host that has
@@ -848,8 +849,8 @@ function useBase316() {
848
849
  return value;
849
850
  }
850
851
  function useSession() {
851
- const { session, loading } = useBase316();
852
- return { session, loading };
852
+ const { session, loading: loading2 } = useBase316();
853
+ return { session, loading: loading2 };
853
854
  }
854
855
 
855
856
  // src/Branding.tsx
@@ -2711,8 +2712,72 @@ function SocialSignIn({
2711
2712
 
2712
2713
  // src/SignUp.tsx
2713
2714
  var import_sdk5 = require("@base316/sdk");
2715
+ var import_react10 = require("react");
2716
+
2717
+ // src/CaptchaWidget.tsx
2714
2718
  var import_react9 = require("react");
2715
2719
  var import_jsx_runtime11 = require("react/jsx-runtime");
2720
+ var SCRIPT_URL = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
2721
+ var loading = null;
2722
+ function loadTurnstile() {
2723
+ if (window.turnstile) {
2724
+ return Promise.resolve(window.turnstile);
2725
+ }
2726
+ loading ??= new Promise((resolve, reject) => {
2727
+ const script = document.createElement("script");
2728
+ script.src = SCRIPT_URL;
2729
+ script.async = true;
2730
+ script.onload = () => {
2731
+ if (window.turnstile) {
2732
+ resolve(window.turnstile);
2733
+ } else {
2734
+ reject(new Error("Turnstile did not start"));
2735
+ }
2736
+ };
2737
+ script.onerror = () => {
2738
+ loading = null;
2739
+ reject(new Error("Turnstile could not be loaded"));
2740
+ };
2741
+ document.head.appendChild(script);
2742
+ });
2743
+ return loading;
2744
+ }
2745
+ function CaptchaWidget({
2746
+ siteKey,
2747
+ onToken
2748
+ }) {
2749
+ const container = (0, import_react9.useRef)(null);
2750
+ const latest = (0, import_react9.useRef)(onToken);
2751
+ (0, import_react9.useEffect)(() => {
2752
+ latest.current = onToken;
2753
+ }, [onToken]);
2754
+ (0, import_react9.useEffect)(() => {
2755
+ let widgetId = null;
2756
+ let cancelled = false;
2757
+ loadTurnstile().then((turnstile) => {
2758
+ if (cancelled || !container.current) {
2759
+ return;
2760
+ }
2761
+ widgetId = turnstile.render(container.current, {
2762
+ sitekey: siteKey,
2763
+ size: "flexible",
2764
+ callback: (token) => latest.current(token),
2765
+ "expired-callback": () => latest.current(null),
2766
+ "error-callback": () => latest.current(null)
2767
+ });
2768
+ }).catch((cause) => console.error("[base316] CAPTCHA unavailable", cause));
2769
+ return () => {
2770
+ cancelled = true;
2771
+ if (widgetId) {
2772
+ window.turnstile?.remove(widgetId);
2773
+ }
2774
+ };
2775
+ }, [siteKey]);
2776
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: container, className: "b316-captcha" });
2777
+ }
2778
+
2779
+ // src/SignUp.tsx
2780
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2716
2781
  var DEFAULT_SIGN_UP_LABELS = {
2717
2782
  name: "Name",
2718
2783
  email: "Email",
@@ -2732,7 +2797,8 @@ var DEFAULT_SIGN_UP_LABELS = {
2732
2797
  joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
2733
2798
  continueWith: (name) => `Continue with ${name}`,
2734
2799
  or: "or",
2735
- closed: "This application is not accepting new accounts right now."
2800
+ closed: "This application is not accepting new accounts right now.",
2801
+ noMethods: "Creating an account is not available here right now."
2736
2802
  };
2737
2803
  function describeRules(policy, labels) {
2738
2804
  const extras = [
@@ -2761,25 +2827,27 @@ function SignUp({
2761
2827
  const { client, setToken } = useBase316();
2762
2828
  const methodsState = useSignInMethods(client);
2763
2829
  const offered = resolveMethods(methodsState.methods, { social, socialRedirectUrl }, null);
2764
- const [name, setName] = (0, import_react9.useState)("");
2765
- const [email, setEmail] = (0, import_react9.useState)("");
2766
- const [password, setPassword] = (0, import_react9.useState)("");
2767
- const [error, setError] = (0, import_react9.useState)(null);
2768
- const [busy, setBusy] = (0, import_react9.useState)(false);
2769
- const [policy, setPolicy] = (0, import_react9.useState)(null);
2770
- const [pending, setPending] = (0, import_react9.useState)(null);
2771
- const [confirmEmail, setConfirmEmail] = (0, import_react9.useState)(false);
2772
- const [urlInvitation, setUrlInvitation] = (0, import_react9.useState)(null);
2773
- const [loaded, setLoaded] = (0, import_react9.useState)(null);
2830
+ const [name, setName] = (0, import_react10.useState)("");
2831
+ const [email, setEmail] = (0, import_react10.useState)("");
2832
+ const [password, setPassword] = (0, import_react10.useState)("");
2833
+ const [error, setError] = (0, import_react10.useState)(null);
2834
+ const [busy, setBusy] = (0, import_react10.useState)(false);
2835
+ const [policy, setPolicy] = (0, import_react10.useState)(null);
2836
+ const [pending, setPending] = (0, import_react10.useState)(null);
2837
+ const [confirmEmail, setConfirmEmail] = (0, import_react10.useState)(false);
2838
+ const [urlInvitation, setUrlInvitation] = (0, import_react10.useState)(null);
2839
+ const [loaded, setLoaded] = (0, import_react10.useState)(null);
2840
+ const [captchaToken, setCaptchaToken] = (0, import_react10.useState)(null);
2841
+ const [captchaRound, setCaptchaRound] = (0, import_react10.useState)(0);
2774
2842
  const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
2775
2843
  const preview = loaded && loaded.token === invitation ? loaded.preview : null;
2776
- (0, import_react9.useEffect)(() => {
2844
+ (0, import_react10.useEffect)(() => {
2777
2845
  if (suppliedInvitation !== void 0 || typeof window === "undefined") {
2778
2846
  return;
2779
2847
  }
2780
2848
  setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
2781
2849
  }, [suppliedInvitation]);
2782
- (0, import_react9.useEffect)(() => {
2850
+ (0, import_react10.useEffect)(() => {
2783
2851
  if (!invitation) {
2784
2852
  return;
2785
2853
  }
@@ -2794,7 +2862,7 @@ function SignUp({
2794
2862
  cancelled = true;
2795
2863
  };
2796
2864
  }, [client, invitation]);
2797
- (0, import_react9.useEffect)(() => {
2865
+ (0, import_react10.useEffect)(() => {
2798
2866
  let cancelled = false;
2799
2867
  client.auth.passwordPolicy().then((loaded2) => {
2800
2868
  if (!cancelled) {
@@ -2814,7 +2882,8 @@ function SignUp({
2814
2882
  email,
2815
2883
  password,
2816
2884
  name: name || void 0,
2817
- invitationToken: invitation ?? void 0
2885
+ invitationToken: invitation ?? void 0,
2886
+ captchaToken: captchaToken ?? void 0
2818
2887
  });
2819
2888
  if (created.invitationAccepted && created.organizationId) {
2820
2889
  onJoined?.(created.organizationId);
@@ -2824,6 +2893,8 @@ function SignUp({
2824
2893
  setError(
2825
2894
  cause instanceof import_sdk5.Base316Error && (cause.code === "INVALID_REQUEST" || cause.code === "RATE_LIMITED" || cause.code === "CONFLICT") && cause.message ? cause.message : labels.genericError
2826
2895
  );
2896
+ setCaptchaToken(null);
2897
+ setCaptchaRound((round) => round + 1);
2827
2898
  setBusy(false);
2828
2899
  return;
2829
2900
  }
@@ -2852,21 +2923,24 @@ function SignUp({
2852
2923
  }
2853
2924
  }
2854
2925
  if (pending) {
2855
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2926
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2856
2927
  }
2857
2928
  if (confirmEmail) {
2858
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cls("b316-card", className), style, children: [
2859
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2860
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2929
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cls("b316-card", className), style, children: [
2930
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2931
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2861
2932
  ] });
2862
2933
  }
2863
2934
  if (!offered.signUp && !invitation) {
2864
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.closed }) });
2935
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("output", { className: "b316-muted", children: labels.closed }) });
2865
2936
  }
2866
2937
  const socialOptions = invitation ? [] : offered.social;
2867
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2868
- socialOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2869
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2938
+ if (!offered.password && socialOptions.length === 0) {
2939
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("output", { className: "b316-muted", children: labels.noMethods }) });
2940
+ }
2941
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2942
+ socialOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2943
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2870
2944
  SocialButtons,
2871
2945
  {
2872
2946
  options: socialOptions,
@@ -2889,14 +2963,14 @@ function SignUp({
2889
2963
  }
2890
2964
  }
2891
2965
  ),
2892
- offered.password ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-divider", children: labels.or }) : null
2966
+ offered.password ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-divider", children: labels.or }) : null
2893
2967
  ] }) : null,
2894
- preview ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2895
- error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2896
- offered.password || socialOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2897
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2898
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2899
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2968
+ preview ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2969
+ error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2970
+ offered.password || socialOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2971
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-field", children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2973
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2900
2974
  "input",
2901
2975
  {
2902
2976
  id: "b316-name",
@@ -2907,9 +2981,9 @@ function SignUp({
2907
2981
  }
2908
2982
  )
2909
2983
  ] }),
2910
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2911
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2912
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2984
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-field", children: [
2985
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2986
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2913
2987
  "input",
2914
2988
  {
2915
2989
  id: "b316-signup-email",
@@ -2922,9 +2996,9 @@ function SignUp({
2922
2996
  }
2923
2997
  )
2924
2998
  ] }),
2925
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2926
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2927
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2999
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-field", children: [
3000
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
3001
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2928
3002
  "input",
2929
3003
  {
2930
3004
  id: "b316-signup-password",
@@ -2939,31 +3013,39 @@ function SignUp({
2939
3013
  required: true
2940
3014
  }
2941
3015
  ),
2942
- policy ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
3016
+ policy ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2943
3017
  ] }),
2944
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
3018
+ methodsState.methods?.captcha && !invitation ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3019
+ CaptchaWidget,
3020
+ {
3021
+ siteKey: methodsState.methods.captcha.siteKey,
3022
+ onToken: setCaptchaToken
3023
+ },
3024
+ captchaRound
3025
+ ) : null,
3026
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2945
3027
  ] }) : null
2946
3028
  ] });
2947
3029
  }
2948
3030
 
2949
3031
  // src/UserProfile.tsx
2950
- var import_jsx_runtime12 = require("react/jsx-runtime");
3032
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2951
3033
  function UserProfile({ className, style }) {
2952
- const { session, loading, signOut } = useBase316();
2953
- if (loading) {
2954
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3034
+ const { session, loading: loading2, signOut } = useBase316();
3035
+ if (loading2) {
3036
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2955
3037
  }
2956
3038
  if (!session) {
2957
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
3039
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2958
3040
  }
2959
3041
  const user = session.user ?? {};
2960
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-row", children: [
2961
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2962
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2963
- user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: user.email }) : null,
2964
- user.emailVerified === false ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: "Email not verified" }) : null
3042
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-row", children: [
3043
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
3044
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
3045
+ user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "b316-muted", children: user.email }) : null,
3046
+ user.emailVerified === false ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "b316-muted", children: "Email not verified" }) : null
2965
3047
  ] }),
2966
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3048
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2967
3049
  "button",
2968
3050
  {
2969
3051
  type: "button",
@@ -2977,11 +3059,11 @@ function UserProfile({ className, style }) {
2977
3059
 
2978
3060
  // src/PasskeyManager.tsx
2979
3061
  var import_sdk6 = require("@base316/sdk");
2980
- var import_react11 = require("react");
3062
+ var import_react12 = require("react");
2981
3063
 
2982
3064
  // src/confirm.tsx
2983
- var import_react10 = require("react");
2984
- var import_jsx_runtime13 = require("react/jsx-runtime");
3065
+ var import_react11 = require("react");
3066
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2985
3067
  var DEFAULT_TIMEOUT_MS = 5e3;
2986
3068
  function ConfirmButton({
2987
3069
  children,
@@ -2991,9 +3073,9 @@ function ConfirmButton({
2991
3073
  disabled,
2992
3074
  timeoutMs = DEFAULT_TIMEOUT_MS
2993
3075
  }) {
2994
- const [armed, setArmed] = (0, import_react10.useState)(false);
2995
- const confirmRef = (0, import_react10.useRef)(null);
2996
- (0, import_react10.useEffect)(() => {
3076
+ const [armed, setArmed] = (0, import_react11.useState)(false);
3077
+ const confirmRef = (0, import_react11.useRef)(null);
3078
+ (0, import_react11.useEffect)(() => {
2997
3079
  if (!armed) {
2998
3080
  return;
2999
3081
  }
@@ -3002,7 +3084,7 @@ function ConfirmButton({
3002
3084
  return () => clearTimeout(timer);
3003
3085
  }, [armed, timeoutMs]);
3004
3086
  if (!armed) {
3005
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3087
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3006
3088
  "button",
3007
3089
  {
3008
3090
  type: "button",
@@ -3016,8 +3098,8 @@ function ConfirmButton({
3016
3098
  return (
3017
3099
  // No `role="group"`: both buttons already say what they do, and the
3018
3100
  // grouping would only repeat the question a screen reader has just read.
3019
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "b316-confirm", children: [
3020
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3101
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "b316-confirm", children: [
3102
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3021
3103
  "button",
3022
3104
  {
3023
3105
  ref: confirmRef,
@@ -3031,7 +3113,7 @@ function ConfirmButton({
3031
3113
  children: confirmLabel
3032
3114
  }
3033
3115
  ),
3034
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3116
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3035
3117
  "button",
3036
3118
  {
3037
3119
  type: "button",
@@ -3045,19 +3127,19 @@ function ConfirmButton({
3045
3127
  }
3046
3128
 
3047
3129
  // src/PasskeyManager.tsx
3048
- var import_jsx_runtime14 = require("react/jsx-runtime");
3130
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3049
3131
  function PasskeyManager({
3050
3132
  className,
3051
3133
  style,
3052
3134
  title = "Passkeys"
3053
3135
  }) {
3054
3136
  const { client, token, session } = useBase316();
3055
- const [passkeys, setPasskeys] = (0, import_react11.useState)(null);
3056
- const [busy, setBusy] = (0, import_react11.useState)(false);
3057
- const [error, setError] = (0, import_react11.useState)(null);
3058
- const [name, setName] = (0, import_react11.useState)("");
3059
- const [supported, setSupported] = (0, import_react11.useState)(false);
3060
- const load = (0, import_react11.useCallback)(async () => {
3137
+ const [passkeys, setPasskeys] = (0, import_react12.useState)(null);
3138
+ const [busy, setBusy] = (0, import_react12.useState)(false);
3139
+ const [error, setError] = (0, import_react12.useState)(null);
3140
+ const [name, setName] = (0, import_react12.useState)("");
3141
+ const [supported, setSupported] = (0, import_react12.useState)(false);
3142
+ const load = (0, import_react12.useCallback)(async () => {
3061
3143
  if (!token) {
3062
3144
  return;
3063
3145
  }
@@ -3070,7 +3152,7 @@ function PasskeyManager({
3070
3152
  setPasskeys(null);
3071
3153
  }
3072
3154
  }, [client, token]);
3073
- (0, import_react11.useEffect)(() => {
3155
+ (0, import_react12.useEffect)(() => {
3074
3156
  if (!(0, import_sdk6.isPasskeySupported)()) {
3075
3157
  return;
3076
3158
  }
@@ -3106,18 +3188,18 @@ function PasskeyManager({
3106
3188
  setError(caught instanceof Error ? caught.message : "That did not work.");
3107
3189
  }
3108
3190
  };
3109
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card", className), style, children: [
3110
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
3111
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
3112
- passkeys === null ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
3113
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3114
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: passkey.name || "Passkey" }),
3115
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-muted", children: [
3191
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card", className), style, children: [
3192
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
3193
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
3194
+ passkeys === null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
3195
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3196
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { children: passkey.name || "Passkey" }),
3197
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
3116
3198
  passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
3117
3199
  passkey.backedUp ? "" : " \xB7 this device only"
3118
3200
  ] })
3119
3201
  ] }),
3120
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3202
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3121
3203
  ConfirmButton,
3122
3204
  {
3123
3205
  className: "b316-button b316-button-secondary",
@@ -3127,9 +3209,9 @@ function PasskeyManager({
3127
3209
  }
3128
3210
  )
3129
3211
  ] }, passkey.id)) }),
3130
- error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
3131
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
3132
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3212
+ error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
3213
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
3214
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3133
3215
  "input",
3134
3216
  {
3135
3217
  className: "b316-input",
@@ -3138,7 +3220,7 @@ function PasskeyManager({
3138
3220
  onChange: (event) => setName(event.target.value)
3139
3221
  }
3140
3222
  ),
3141
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
3223
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
3142
3224
  ] })
3143
3225
  ] });
3144
3226
  }
@@ -3148,8 +3230,8 @@ function formatDate(value) {
3148
3230
  }
3149
3231
 
3150
3232
  // src/ActiveSessions.tsx
3151
- var import_react12 = require("react");
3152
- var import_jsx_runtime15 = require("react/jsx-runtime");
3233
+ var import_react13 = require("react");
3234
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3153
3235
  function describeDevice(userAgent) {
3154
3236
  if (!userAgent) {
3155
3237
  return null;
@@ -3167,10 +3249,10 @@ function when(value) {
3167
3249
  }
3168
3250
  function ActiveSessions({ onRevoked, className, style }) {
3169
3251
  const { client, token } = useBase316();
3170
- const [sessions, setSessions] = (0, import_react12.useState)(null);
3171
- const [error, setError] = (0, import_react12.useState)(null);
3172
- const [busy, setBusy] = (0, import_react12.useState)(false);
3173
- const load = (0, import_react12.useCallback)(() => {
3252
+ const [sessions, setSessions] = (0, import_react13.useState)(null);
3253
+ const [error, setError] = (0, import_react13.useState)(null);
3254
+ const [busy, setBusy] = (0, import_react13.useState)(false);
3255
+ const load = (0, import_react13.useCallback)(() => {
3174
3256
  if (!token) {
3175
3257
  return;
3176
3258
  }
@@ -3181,15 +3263,15 @@ function ActiveSessions({ onRevoked, className, style }) {
3181
3263
  setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
3182
3264
  });
3183
3265
  }, [client, token]);
3184
- (0, import_react12.useEffect)(load, [load]);
3266
+ (0, import_react13.useEffect)(load, [load]);
3185
3267
  if (!token) {
3186
3268
  return null;
3187
3269
  }
3188
3270
  if (error) {
3189
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
3271
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
3190
3272
  }
3191
3273
  if (!sessions) {
3192
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3274
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3193
3275
  }
3194
3276
  async function revokeOthers() {
3195
3277
  setBusy(true);
@@ -3203,32 +3285,32 @@ function ActiveSessions({ onRevoked, className, style }) {
3203
3285
  setBusy(false);
3204
3286
  }
3205
3287
  }
3206
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
3207
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-sessions-head", children: [
3208
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
3209
- sessions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
3288
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
3289
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-sessions-head", children: [
3290
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
3291
+ sessions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
3210
3292
  ] }),
3211
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("li", { className: "b316-session", children: [
3212
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-session-device", children: [
3293
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("li", { className: "b316-session", children: [
3294
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-session-device", children: [
3213
3295
  describeDevice(session.userAgent) ?? "Unknown device",
3214
3296
  session.impersonatedBy ? (
3215
3297
  // Worth saying loudly: somebody is acting as this account.
3216
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "b316-chip", children: " Support access" })
3298
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "b316-chip", children: " Support access" })
3217
3299
  ) : null
3218
3300
  ] }),
3219
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
3301
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-muted", children: [
3220
3302
  session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
3221
3303
  "last used ",
3222
3304
  when(session.lastSeenAt)
3223
3305
  ] })
3224
3306
  ] }, session.id)) }),
3225
- sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
3307
+ sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
3226
3308
  ] });
3227
3309
  }
3228
3310
 
3229
3311
  // src/DeviceApproval.tsx
3230
- var import_react13 = require("react");
3231
- var import_jsx_runtime16 = require("react/jsx-runtime");
3312
+ var import_react14 = require("react");
3313
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3232
3314
  function DeviceApproval({
3233
3315
  userCode = "",
3234
3316
  onDecided,
@@ -3236,11 +3318,11 @@ function DeviceApproval({
3236
3318
  style
3237
3319
  }) {
3238
3320
  const { client, token } = useBase316();
3239
- const [code, setCode] = (0, import_react13.useState)(userCode);
3240
- const [request, setRequest] = (0, import_react13.useState)(null);
3241
- const [decided, setDecided] = (0, import_react13.useState)(null);
3242
- const [error, setError] = (0, import_react13.useState)(null);
3243
- const [busy, setBusy] = (0, import_react13.useState)(false);
3321
+ const [code, setCode] = (0, import_react14.useState)(userCode);
3322
+ const [request, setRequest] = (0, import_react14.useState)(null);
3323
+ const [decided, setDecided] = (0, import_react14.useState)(null);
3324
+ const [error, setError] = (0, import_react14.useState)(null);
3325
+ const [busy, setBusy] = (0, import_react14.useState)(false);
3244
3326
  if (!token) {
3245
3327
  return null;
3246
3328
  }
@@ -3273,25 +3355,25 @@ function DeviceApproval({
3273
3355
  }
3274
3356
  }
3275
3357
  if (decided !== null) {
3276
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3277
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
3278
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
3358
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3359
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
3360
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
3279
3361
  ] });
3280
3362
  }
3281
3363
  if (request) {
3282
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3283
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("h3", { className: "b316-device-title", children: [
3364
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3365
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("h3", { className: "b316-device-title", children: [
3284
3366
  "Sign in to ",
3285
3367
  request.clientName
3286
3368
  ] }),
3287
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "b316-muted", children: [
3369
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { className: "b316-muted", children: [
3288
3370
  request.clientName,
3289
3371
  " is asking to sign in as you."
3290
3372
  ] }),
3291
- request.scopes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: scope }, scope)) }) : null,
3292
- error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3293
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-device-actions", children: [
3294
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3373
+ request.scopes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("li", { children: scope }, scope)) }) : null,
3374
+ error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3375
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-device-actions", children: [
3376
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3295
3377
  "button",
3296
3378
  {
3297
3379
  type: "button",
@@ -3301,7 +3383,7 @@ function DeviceApproval({
3301
3383
  children: busy ? "Approving\u2026" : "Approve"
3302
3384
  }
3303
3385
  ),
3304
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3386
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3305
3387
  "button",
3306
3388
  {
3307
3389
  type: "button",
@@ -3314,11 +3396,11 @@ function DeviceApproval({
3314
3396
  ] })
3315
3397
  ] });
3316
3398
  }
3317
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
3318
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
3319
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
3320
- error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3321
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3399
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
3400
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
3401
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
3402
+ error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3403
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3322
3404
  "input",
3323
3405
  {
3324
3406
  className: "b316-input",
@@ -3331,13 +3413,13 @@ function DeviceApproval({
3331
3413
  "aria-label": "Device code"
3332
3414
  }
3333
3415
  ),
3334
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
3416
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
3335
3417
  ] });
3336
3418
  }
3337
3419
 
3338
3420
  // src/PrivacyControls.tsx
3339
- var import_react14 = require("react");
3340
- var import_jsx_runtime17 = require("react/jsx-runtime");
3421
+ var import_react15 = require("react");
3422
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3341
3423
  function PrivacyControls({
3342
3424
  confirmWord = "DELETE",
3343
3425
  onErased,
@@ -3345,10 +3427,10 @@ function PrivacyControls({
3345
3427
  style
3346
3428
  }) {
3347
3429
  const { client, token } = useBase316();
3348
- const [confirming, setConfirming] = (0, import_react14.useState)(false);
3349
- const [typed, setTyped] = (0, import_react14.useState)("");
3350
- const [error, setError] = (0, import_react14.useState)(null);
3351
- const [busy, setBusy] = (0, import_react14.useState)(false);
3430
+ const [confirming, setConfirming] = (0, import_react15.useState)(false);
3431
+ const [typed, setTyped] = (0, import_react15.useState)("");
3432
+ const [error, setError] = (0, import_react15.useState)(null);
3433
+ const [busy, setBusy] = (0, import_react15.useState)(false);
3352
3434
  if (!token) {
3353
3435
  return null;
3354
3436
  }
@@ -3383,22 +3465,22 @@ function PrivacyControls({
3383
3465
  setBusy(false);
3384
3466
  }
3385
3467
  }
3386
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
3387
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
3388
- error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3389
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
3390
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3391
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Download a copy" }),
3392
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
3468
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
3469
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
3470
+ error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3471
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-privacy-row", children: [
3472
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
3473
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { children: "Download a copy" }),
3474
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
3393
3475
  ] }),
3394
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3476
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3395
3477
  ] }),
3396
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
3397
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3398
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Delete your account" }),
3399
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3478
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-privacy-row", children: [
3479
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
3480
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { children: "Delete your account" }),
3481
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3400
3482
  ] }),
3401
- confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3483
+ confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3402
3484
  "button",
3403
3485
  {
3404
3486
  type: "button",
@@ -3409,13 +3491,13 @@ function PrivacyControls({
3409
3491
  }
3410
3492
  )
3411
3493
  ] }),
3412
- confirming ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-confirm", children: [
3413
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3494
+ confirming ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-privacy-confirm", children: [
3495
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3414
3496
  "Type ",
3415
3497
  confirmWord,
3416
3498
  " to confirm"
3417
3499
  ] }),
3418
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3500
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3419
3501
  "input",
3420
3502
  {
3421
3503
  id: "b316-privacy-confirm",
@@ -3425,8 +3507,8 @@ function PrivacyControls({
3425
3507
  onChange: (event) => setTyped(event.target.value)
3426
3508
  }
3427
3509
  ),
3428
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-actions", children: [
3429
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3510
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-privacy-actions", children: [
3511
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3430
3512
  "button",
3431
3513
  {
3432
3514
  type: "button",
@@ -3438,7 +3520,7 @@ function PrivacyControls({
3438
3520
  children: "Cancel"
3439
3521
  }
3440
3522
  ),
3441
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3523
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3442
3524
  "button",
3443
3525
  {
3444
3526
  type: "button",
@@ -3454,12 +3536,12 @@ function PrivacyControls({
3454
3536
  }
3455
3537
 
3456
3538
  // src/TwoFactorManager.tsx
3457
- var import_react16 = require("react");
3539
+ var import_react17 = require("react");
3458
3540
 
3459
3541
  // src/QrCode.tsx
3460
3542
  var import_qrcode_generator = __toESM(require("qrcode-generator"));
3461
- var import_react15 = require("react");
3462
- var import_jsx_runtime18 = require("react/jsx-runtime");
3543
+ var import_react16 = require("react");
3544
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3463
3545
  var QUIET_ZONE = 4;
3464
3546
  function utf8Binary(value) {
3465
3547
  let binary = "";
@@ -3484,9 +3566,9 @@ function qrPath(value) {
3484
3566
  return { path, modules };
3485
3567
  }
3486
3568
  function QrCode({ value, label, size = 180, className }) {
3487
- const { path, modules } = (0, import_react15.useMemo)(() => qrPath(value), [value]);
3569
+ const { path, modules } = (0, import_react16.useMemo)(() => qrPath(value), [value]);
3488
3570
  const extent = modules + QUIET_ZONE * 2;
3489
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3571
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3490
3572
  "svg",
3491
3573
  {
3492
3574
  className,
@@ -3498,15 +3580,15 @@ function QrCode({ value, label, size = 180, className }) {
3498
3580
  shapeRendering: "crispEdges",
3499
3581
  xmlns: "http://www.w3.org/2000/svg",
3500
3582
  children: [
3501
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3502
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: path, fill: "#000000" })
3583
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3584
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: path, fill: "#000000" })
3503
3585
  ]
3504
3586
  }
3505
3587
  );
3506
3588
  }
3507
3589
 
3508
3590
  // src/TwoFactorManager.tsx
3509
- var import_jsx_runtime19 = require("react/jsx-runtime");
3591
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3510
3592
  function groupKey(secret) {
3511
3593
  return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3512
3594
  }
@@ -3519,12 +3601,12 @@ function TwoFactorManager({
3519
3601
  style
3520
3602
  }) {
3521
3603
  const { client, token } = useBase316();
3522
- const [stage, setStage] = (0, import_react16.useState)({ name: "idle" });
3523
- const [on, setOn] = (0, import_react16.useState)(enabled);
3524
- const [code, setCode] = (0, import_react16.useState)("");
3525
- const [phone, setPhone] = (0, import_react16.useState)("");
3526
- const [error, setError] = (0, import_react16.useState)(null);
3527
- const [busy, setBusy] = (0, import_react16.useState)(false);
3604
+ const [stage, setStage] = (0, import_react17.useState)({ name: "idle" });
3605
+ const [on, setOn] = (0, import_react17.useState)(enabled);
3606
+ const [code, setCode] = (0, import_react17.useState)("");
3607
+ const [phone, setPhone] = (0, import_react17.useState)("");
3608
+ const [error, setError] = (0, import_react17.useState)(null);
3609
+ const [busy, setBusy] = (0, import_react17.useState)(false);
3528
3610
  if (!token) {
3529
3611
  return null;
3530
3612
  }
@@ -3602,17 +3684,17 @@ function TwoFactorManager({
3602
3684
  setBusy(false);
3603
3685
  }
3604
3686
  }
3605
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3606
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3607
- error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3608
- stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-codes", children: [
3609
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3610
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { children: recovery }) }, recovery)) }),
3611
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3612
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3613
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3614
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3615
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3687
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3688
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3689
+ error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3690
+ stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-codes", children: [
3691
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3692
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("code", { children: recovery }) }, recovery)) }),
3693
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3694
+ ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-enrol", children: [
3695
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3696
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3697
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3616
3698
  "input",
3617
3699
  {
3618
3700
  id: "b316-mfa-phone",
@@ -3624,8 +3706,8 @@ function TwoFactorManager({
3624
3706
  onChange: (event) => setPhone(event.target.value)
3625
3707
  }
3626
3708
  ),
3627
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3628
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3709
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-actions", children: [
3710
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3629
3711
  "button",
3630
3712
  {
3631
3713
  type: "button",
@@ -3634,16 +3716,16 @@ function TwoFactorManager({
3634
3716
  children: "Cancel"
3635
3717
  }
3636
3718
  ),
3637
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3719
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3638
3720
  ] })
3639
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3640
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { children: [
3721
+ ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-enrol", children: [
3722
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { children: [
3641
3723
  "We sent a code to ",
3642
3724
  stage.destinationHint,
3643
3725
  ". Enter it below to turn this on."
3644
3726
  ] }),
3645
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3646
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3727
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3728
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3647
3729
  "input",
3648
3730
  {
3649
3731
  id: "b316-mfa-code",
@@ -3654,8 +3736,8 @@ function TwoFactorManager({
3654
3736
  onChange: (event) => setCode(event.target.value)
3655
3737
  }
3656
3738
  ),
3657
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3658
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3739
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-actions", children: [
3740
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3659
3741
  "button",
3660
3742
  {
3661
3743
  type: "button",
@@ -3664,7 +3746,7 @@ function TwoFactorManager({
3664
3746
  children: "Cancel"
3665
3747
  }
3666
3748
  ),
3667
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3749
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3668
3750
  "button",
3669
3751
  {
3670
3752
  type: "button",
@@ -3675,9 +3757,9 @@ function TwoFactorManager({
3675
3757
  }
3676
3758
  )
3677
3759
  ] })
3678
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3679
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3680
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3760
+ ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-enrol", children: [
3761
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3762
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3681
3763
  QrCode,
3682
3764
  {
3683
3765
  className: "b316-mfa-qr",
@@ -3685,13 +3767,13 @@ function TwoFactorManager({
3685
3767
  label: "QR code for your authenticator app"
3686
3768
  }
3687
3769
  ),
3688
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-secret", children: [
3689
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3690
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3770
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-secret", children: [
3771
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3772
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3691
3773
  ] }),
3692
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3693
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3694
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3774
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3775
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3776
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3695
3777
  "input",
3696
3778
  {
3697
3779
  id: "b316-mfa-code",
@@ -3702,8 +3784,8 @@ function TwoFactorManager({
3702
3784
  onChange: (event) => setCode(event.target.value)
3703
3785
  }
3704
3786
  ),
3705
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3706
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3787
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-actions", children: [
3788
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3707
3789
  "button",
3708
3790
  {
3709
3791
  type: "button",
@@ -3712,7 +3794,7 @@ function TwoFactorManager({
3712
3794
  children: "Cancel"
3713
3795
  }
3714
3796
  ),
3715
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3797
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3716
3798
  "button",
3717
3799
  {
3718
3800
  type: "button",
@@ -3723,9 +3805,9 @@ function TwoFactorManager({
3723
3805
  }
3724
3806
  )
3725
3807
  ] })
3726
- ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-on", children: [
3727
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3728
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3808
+ ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-on", children: [
3809
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3810
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3729
3811
  ConfirmButton,
3730
3812
  {
3731
3813
  className: "b316-button-quiet b316-danger",
@@ -3735,11 +3817,11 @@ function TwoFactorManager({
3735
3817
  children: "Turn off"
3736
3818
  }
3737
3819
  )
3738
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-off", children: [
3739
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3740
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3741
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3742
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3820
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-off", children: [
3821
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3822
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-mfa-actions", children: [
3823
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3824
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3743
3825
  "button",
3744
3826
  {
3745
3827
  type: "button",
@@ -3749,7 +3831,7 @@ function TwoFactorManager({
3749
3831
  children: "Email me a code"
3750
3832
  }
3751
3833
  ),
3752
- allowSms ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3834
+ allowSms ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3753
3835
  "button",
3754
3836
  {
3755
3837
  type: "button",
@@ -3765,14 +3847,14 @@ function TwoFactorManager({
3765
3847
  }
3766
3848
 
3767
3849
  // src/ForgotPassword.tsx
3768
- var import_react17 = require("react");
3769
- var import_jsx_runtime20 = require("react/jsx-runtime");
3850
+ var import_react18 = require("react");
3851
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3770
3852
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3771
3853
  const { client } = useBase316();
3772
- const [email, setEmail] = (0, import_react17.useState)("");
3773
- const [sent, setSent] = (0, import_react17.useState)(false);
3774
- const [busy, setBusy] = (0, import_react17.useState)(false);
3775
- const [error, setError] = (0, import_react17.useState)(null);
3854
+ const [email, setEmail] = (0, import_react18.useState)("");
3855
+ const [sent, setSent] = (0, import_react18.useState)(false);
3856
+ const [busy, setBusy] = (0, import_react18.useState)(false);
3857
+ const [error, setError] = (0, import_react18.useState)(null);
3776
3858
  async function submit(event) {
3777
3859
  event.preventDefault();
3778
3860
  setBusy(true);
@@ -3788,22 +3870,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3788
3870
  }
3789
3871
  }
3790
3872
  if (sent) {
3791
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cls("b316-card", className), style, children: [
3792
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3793
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { className: "b316-muted", children: [
3873
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3874
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3875
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "b316-muted", children: [
3794
3876
  "If there is an account for ",
3795
3877
  email.trim(),
3796
3878
  ", a link to set a new password is on its way."
3797
3879
  ] }),
3798
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3880
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3799
3881
  ] });
3800
3882
  }
3801
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3802
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3803
- error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3804
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-field", children: [
3805
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3806
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3883
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3884
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3885
+ error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3886
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
3887
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3888
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3807
3889
  "input",
3808
3890
  {
3809
3891
  id: "b316-forgot-email",
@@ -3816,14 +3898,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3816
3898
  }
3817
3899
  )
3818
3900
  ] }),
3819
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3820
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3901
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3902
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3821
3903
  ] });
3822
3904
  }
3823
3905
 
3824
3906
  // src/ResetPassword.tsx
3825
- var import_react18 = require("react");
3826
- var import_jsx_runtime21 = require("react/jsx-runtime");
3907
+ var import_react19 = require("react");
3908
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3827
3909
  function ResetPassword({
3828
3910
  token: supplied,
3829
3911
  onReset,
@@ -3832,13 +3914,13 @@ function ResetPassword({
3832
3914
  style
3833
3915
  }) {
3834
3916
  const { client } = useBase316();
3835
- const [token, setToken] = (0, import_react18.useState)(supplied ?? null);
3836
- const [password, setPassword] = (0, import_react18.useState)("");
3837
- const [confirmation, setConfirmation] = (0, import_react18.useState)("");
3838
- const [done, setDone] = (0, import_react18.useState)(false);
3839
- const [busy, setBusy] = (0, import_react18.useState)(false);
3840
- const [error, setError] = (0, import_react18.useState)(null);
3841
- (0, import_react18.useEffect)(() => {
3917
+ const [token, setToken] = (0, import_react19.useState)(supplied ?? null);
3918
+ const [password, setPassword] = (0, import_react19.useState)("");
3919
+ const [confirmation, setConfirmation] = (0, import_react19.useState)("");
3920
+ const [done, setDone] = (0, import_react19.useState)(false);
3921
+ const [busy, setBusy] = (0, import_react19.useState)(false);
3922
+ const [error, setError] = (0, import_react19.useState)(null);
3923
+ (0, import_react19.useEffect)(() => {
3842
3924
  if (supplied || typeof window === "undefined") {
3843
3925
  return;
3844
3926
  }
@@ -3873,24 +3955,24 @@ function ResetPassword({
3873
3955
  }
3874
3956
  }
3875
3957
  if (done) {
3876
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3877
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3878
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3879
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3958
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card", className), style, children: [
3959
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3960
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3961
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3880
3962
  ] });
3881
3963
  }
3882
3964
  if (!token) {
3883
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3884
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3885
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3965
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card", className), style, children: [
3966
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3967
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3886
3968
  ] });
3887
3969
  }
3888
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3889
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3890
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3891
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
3892
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3893
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3970
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3971
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3972
+ error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3973
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "b316-field", children: [
3974
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3975
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3894
3976
  "input",
3895
3977
  {
3896
3978
  id: "b316-reset-password",
@@ -3903,9 +3985,9 @@ function ResetPassword({
3903
3985
  }
3904
3986
  )
3905
3987
  ] }),
3906
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
3907
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3908
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3988
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "b316-field", children: [
3989
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3990
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3909
3991
  "input",
3910
3992
  {
3911
3993
  id: "b316-reset-confirm",
@@ -3918,13 +4000,13 @@ function ResetPassword({
3918
4000
  }
3919
4001
  )
3920
4002
  ] }),
3921
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
4003
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3922
4004
  ] });
3923
4005
  }
3924
4006
 
3925
4007
  // src/VerifyEmail.tsx
3926
- var import_react19 = require("react");
3927
- var import_jsx_runtime22 = require("react/jsx-runtime");
4008
+ var import_react20 = require("react");
4009
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3928
4010
  function VerifyEmail({
3929
4011
  token: supplied,
3930
4012
  onVerified,
@@ -3933,9 +4015,9 @@ function VerifyEmail({
3933
4015
  style
3934
4016
  }) {
3935
4017
  const { client } = useBase316();
3936
- const [state, setState] = (0, import_react19.useState)("waiting");
3937
- const spent = (0, import_react19.useRef)(false);
3938
- (0, import_react19.useEffect)(() => {
4018
+ const [state, setState] = (0, import_react20.useState)("waiting");
4019
+ const spent = (0, import_react20.useRef)(false);
4020
+ (0, import_react20.useEffect)(() => {
3939
4021
  if (spent.current) {
3940
4022
  return;
3941
4023
  }
@@ -3961,22 +4043,22 @@ function VerifyEmail({
3961
4043
  setState("failed");
3962
4044
  });
3963
4045
  }, [client, supplied, onVerified]);
3964
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3965
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3966
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3967
- continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3968
- ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3969
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3970
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3971
- ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3972
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3973
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3974
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
4046
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4047
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
4048
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
4049
+ continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
4050
+ ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4051
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
4052
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
4053
+ ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4054
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
4055
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
4056
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3975
4057
  }
3976
4058
 
3977
4059
  // src/TeamMembers.tsx
3978
- var import_react20 = require("react");
3979
- var import_jsx_runtime23 = require("react/jsx-runtime");
4060
+ var import_react21 = require("react");
4061
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3980
4062
  function TeamMembers({
3981
4063
  organizationId,
3982
4064
  onInvited,
@@ -3986,16 +4068,16 @@ function TeamMembers({
3986
4068
  style
3987
4069
  }) {
3988
4070
  const { client, token, session } = useBase316();
3989
- const [teams, setTeams] = (0, import_react20.useState)(null);
3990
- const [members, setMembers] = (0, import_react20.useState)(null);
3991
- const [invitations, setInvitations] = (0, import_react20.useState)(null);
3992
- const [email, setEmail] = (0, import_react20.useState)("");
3993
- const [busy, setBusy] = (0, import_react20.useState)(false);
3994
- const [error, setError] = (0, import_react20.useState)(null);
3995
- const [copied, setCopied] = (0, import_react20.useState)(null);
4071
+ const [teams, setTeams] = (0, import_react21.useState)(null);
4072
+ const [members, setMembers] = (0, import_react21.useState)(null);
4073
+ const [invitations, setInvitations] = (0, import_react21.useState)(null);
4074
+ const [email, setEmail] = (0, import_react21.useState)("");
4075
+ const [busy, setBusy] = (0, import_react21.useState)(false);
4076
+ const [error, setError] = (0, import_react21.useState)(null);
4077
+ const [copied, setCopied] = (0, import_react21.useState)(null);
3996
4078
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3997
4079
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3998
- const load = (0, import_react20.useCallback)(() => {
4080
+ const load = (0, import_react21.useCallback)(() => {
3999
4081
  if (!token) {
4000
4082
  return;
4001
4083
  }
@@ -4003,8 +4085,8 @@ function TeamMembers({
4003
4085
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
4004
4086
  );
4005
4087
  }, [client, token]);
4006
- (0, import_react20.useEffect)(load, [load]);
4007
- (0, import_react20.useEffect)(() => {
4088
+ (0, import_react21.useEffect)(load, [load]);
4089
+ (0, import_react21.useEffect)(() => {
4008
4090
  if (!token || !chosen) {
4009
4091
  return;
4010
4092
  }
@@ -4035,10 +4117,10 @@ function TeamMembers({
4035
4117
  return null;
4036
4118
  }
4037
4119
  if (!teams) {
4038
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
4120
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
4039
4121
  }
4040
4122
  if (!chosen) {
4041
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
4123
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
4042
4124
  }
4043
4125
  const canManage = invitations !== null;
4044
4126
  async function invite(event) {
@@ -4088,30 +4170,30 @@ function TeamMembers({
4088
4170
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
4089
4171
  }
4090
4172
  }
4091
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
4092
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
4173
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
4174
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
4093
4175
  team?.inherited ? (
4094
4176
  // Not a member of this team, so not in the list below and with nothing
4095
4177
  // to leave: access comes from the team that manages it, and ends there.
4096
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
4178
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-muted", children: [
4097
4179
  "You have access through",
4098
4180
  " ",
4099
4181
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
4100
4182
  "."
4101
4183
  ] })
4102
4184
  ) : null,
4103
- error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4104
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
4105
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4106
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
4107
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
4185
+ error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4186
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("li", { className: "b316-team-member", children: [
4187
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
4188
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
4189
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-muted", children: [
4108
4190
  member.user.email,
4109
4191
  member.user.id === session?.userId ? " \xB7 you" : ""
4110
4192
  ] })
4111
4193
  ] }),
4112
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-member-side", children: [
4113
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "b316-chip", children: member.role.name }),
4114
- canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4194
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-team-member-side", children: [
4195
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-chip", children: member.role.name }),
4196
+ canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4115
4197
  ConfirmButton,
4116
4198
  {
4117
4199
  className: "b316-button-quiet b316-danger",
@@ -4123,19 +4205,19 @@ function TeamMembers({
4123
4205
  ) : null
4124
4206
  ] })
4125
4207
  ] }, member.id)) }),
4126
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4127
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
4128
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
4129
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4130
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: invitation.email }),
4131
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
4208
+ canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
4209
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
4210
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("li", { className: "b316-team-member", children: [
4211
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
4212
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { children: invitation.email }),
4213
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-muted", children: [
4132
4214
  invitation.role.name,
4133
4215
  " \xB7 expires",
4134
4216
  " ",
4135
4217
  new Date(invitation.expiresAt).toLocaleDateString()
4136
4218
  ] })
4137
4219
  ] }),
4138
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4220
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4139
4221
  "button",
4140
4222
  {
4141
4223
  type: "button",
@@ -4146,10 +4228,10 @@ function TeamMembers({
4146
4228
  )
4147
4229
  ] }, invitation.id)) })
4148
4230
  ] }) : null,
4149
- canManage ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
4150
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
4151
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-invite-row", children: [
4152
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4231
+ canManage ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
4232
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
4233
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-team-invite-row", children: [
4234
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4153
4235
  "input",
4154
4236
  {
4155
4237
  id: "b316-invite-email",
@@ -4161,19 +4243,19 @@ function TeamMembers({
4161
4243
  onChange: (event) => setEmail(event.target.value)
4162
4244
  }
4163
4245
  ),
4164
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
4246
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
4165
4247
  ] })
4166
4248
  ] }) : null,
4167
- copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-link", children: [
4168
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
4169
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("code", { children: copied })
4249
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-team-link", children: [
4250
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
4251
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { children: copied })
4170
4252
  ] }) : null
4171
4253
  ] });
4172
4254
  }
4173
4255
 
4174
4256
  // src/AcceptInvitation.tsx
4175
- var import_react21 = require("react");
4176
- var import_jsx_runtime24 = require("react/jsx-runtime");
4257
+ var import_react22 = require("react");
4258
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4177
4259
  function signUpUrlWithInvitation(url, token) {
4178
4260
  const [beforeHash, ...hash] = url.split("#");
4179
4261
  const base = beforeHash ?? "";
@@ -4192,18 +4274,18 @@ function AcceptInvitation({
4192
4274
  style
4193
4275
  }) {
4194
4276
  const { client, token: session, session: user } = useBase316();
4195
- const [invitationToken, setInvitationToken] = (0, import_react21.useState)(supplied ?? null);
4196
- const [preview, setPreview] = (0, import_react21.useState)(null);
4197
- const [state, setState] = (0, import_react21.useState)("loading");
4198
- const [error, setError] = (0, import_react21.useState)(null);
4199
- const [busy, setBusy] = (0, import_react21.useState)(false);
4200
- (0, import_react21.useEffect)(() => {
4277
+ const [invitationToken, setInvitationToken] = (0, import_react22.useState)(supplied ?? null);
4278
+ const [preview, setPreview] = (0, import_react22.useState)(null);
4279
+ const [state, setState] = (0, import_react22.useState)("loading");
4280
+ const [error, setError] = (0, import_react22.useState)(null);
4281
+ const [busy, setBusy] = (0, import_react22.useState)(false);
4282
+ (0, import_react22.useEffect)(() => {
4201
4283
  if (supplied || typeof window === "undefined") {
4202
4284
  return;
4203
4285
  }
4204
4286
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
4205
4287
  }, [supplied]);
4206
- (0, import_react21.useEffect)(() => {
4288
+ (0, import_react22.useEffect)(() => {
4207
4289
  if (!invitationToken) {
4208
4290
  setState(supplied === void 0 ? "loading" : "invalid");
4209
4291
  return;
@@ -4240,42 +4322,42 @@ function AcceptInvitation({
4240
4322
  }
4241
4323
  }
4242
4324
  if (state === "loading") {
4243
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
4325
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
4244
4326
  }
4245
4327
  if (state === "invalid") {
4246
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card", className), style, children: [
4247
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
4248
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
4328
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cls("b316-card", className), style, children: [
4329
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
4330
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
4249
4331
  ] });
4250
4332
  }
4251
4333
  if (state === "accepted") {
4252
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
4334
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("h3", { className: "b316-form-title", children: [
4253
4335
  "You have joined ",
4254
4336
  preview?.organizationName
4255
4337
  ] }) });
4256
4338
  }
4257
4339
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
4258
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
4259
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
4340
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
4341
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("h3", { className: "b316-form-title", children: [
4260
4342
  "Join ",
4261
4343
  preview?.organizationName
4262
4344
  ] }),
4263
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "b316-muted", children: [
4345
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: "b316-muted", children: [
4264
4346
  "Invited as ",
4265
4347
  preview?.email,
4266
4348
  " \xB7 ",
4267
4349
  preview?.roleName
4268
4350
  ] }),
4269
- error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4270
- !session ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
4271
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
4351
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4352
+ !session ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
4353
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { children: [
4272
4354
  "Sign in as ",
4273
4355
  preview?.email,
4274
4356
  " to accept."
4275
4357
  ] }),
4276
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-invitation-actions", children: [
4277
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
4278
- signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4358
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-invitation-actions", children: [
4359
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
4360
+ signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4279
4361
  "a",
4280
4362
  {
4281
4363
  className: "b316-button-link",
@@ -4288,20 +4370,20 @@ function AcceptInvitation({
4288
4370
  // Said before they press anything. The server refuses this, but
4289
4371
  // finding out after a click reads as a broken invitation rather than
4290
4372
  // as being signed in as the wrong person.
4291
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
4373
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { children: [
4292
4374
  "You are signed in as ",
4293
4375
  user?.user.email,
4294
4376
  ". This invitation was sent to ",
4295
4377
  preview?.email,
4296
4378
  " \u2014 sign in as that address to accept it."
4297
4379
  ] })
4298
- ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
4380
+ ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
4299
4381
  ] });
4300
4382
  }
4301
4383
 
4302
4384
  // src/PayInvoice.tsx
4303
- var import_react22 = require("react");
4304
- var import_jsx_runtime25 = require("react/jsx-runtime");
4385
+ var import_react23 = require("react");
4386
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4305
4387
  var STRIPE_SRC = "https://js.stripe.com/v3/";
4306
4388
  function loadStripeScript() {
4307
4389
  if (typeof window === "undefined") {
@@ -4333,14 +4415,14 @@ function PayInvoice({
4333
4415
  style
4334
4416
  }) {
4335
4417
  const { client } = useBase316();
4336
- const mountRef = (0, import_react22.useRef)(null);
4337
- const stripeRef = (0, import_react22.useRef)(null);
4338
- const elementsRef = (0, import_react22.useRef)(null);
4339
- const [ready, setReady] = (0, import_react22.useState)(false);
4340
- const [paying, setPaying] = (0, import_react22.useState)(false);
4341
- const [done, setDone] = (0, import_react22.useState)(false);
4342
- const [error, setError] = (0, import_react22.useState)(null);
4343
- (0, import_react22.useEffect)(() => {
4418
+ const mountRef = (0, import_react23.useRef)(null);
4419
+ const stripeRef = (0, import_react23.useRef)(null);
4420
+ const elementsRef = (0, import_react23.useRef)(null);
4421
+ const [ready, setReady] = (0, import_react23.useState)(false);
4422
+ const [paying, setPaying] = (0, import_react23.useState)(false);
4423
+ const [done, setDone] = (0, import_react23.useState)(false);
4424
+ const [error, setError] = (0, import_react23.useState)(null);
4425
+ (0, import_react23.useEffect)(() => {
4344
4426
  let cancelled = false;
4345
4427
  async function start() {
4346
4428
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -4393,17 +4475,17 @@ function PayInvoice({
4393
4475
  onPaid?.();
4394
4476
  };
4395
4477
  if (done) {
4396
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4478
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4397
4479
  }
4398
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4399
- error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4400
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4401
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4480
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4481
+ error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4482
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4483
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4402
4484
  ] });
4403
4485
  }
4404
4486
 
4405
4487
  // src/usePaymentLink.ts
4406
- var import_react23 = require("react");
4488
+ var import_react24 = require("react");
4407
4489
  function usePaymentLink({
4408
4490
  token,
4409
4491
  environmentId,
@@ -4411,10 +4493,10 @@ function usePaymentLink({
4411
4493
  onPaid
4412
4494
  }) {
4413
4495
  const { client } = useBase316();
4414
- const [status2, setStatus] = (0, import_react23.useState)({ state: "loading" });
4415
- const onPaidRef = (0, import_react23.useRef)(onPaid);
4496
+ const [status2, setStatus] = (0, import_react24.useState)({ state: "loading" });
4497
+ const onPaidRef = (0, import_react24.useRef)(onPaid);
4416
4498
  onPaidRef.current = onPaid;
4417
- (0, import_react23.useEffect)(() => {
4499
+ (0, import_react24.useEffect)(() => {
4418
4500
  let stopped = false;
4419
4501
  let timer;
4420
4502
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4463,23 +4545,23 @@ function usePaymentLink({
4463
4545
  }
4464
4546
 
4465
4547
  // src/PricingTable.tsx
4466
- var import_react25 = require("react");
4548
+ var import_react26 = require("react");
4467
4549
 
4468
4550
  // src/usePlans.ts
4469
- var import_react24 = require("react");
4551
+ var import_react25 = require("react");
4470
4552
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4471
4553
  function usePlans(options = {}) {
4472
4554
  const { client, token } = useBase316();
4473
- const [plans, setPlans] = (0, import_react24.useState)(null);
4474
- const [error, setError] = (0, import_react24.useState)(false);
4475
- const [busyPlanVersionId, setBusy] = (0, import_react24.useState)(null);
4476
- const [lastError, setLastError] = (0, import_react24.useState)(null);
4477
- const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react24.useState)(null);
4478
- const [managedBy, setManagedBy] = (0, import_react24.useState)(null);
4479
- const [reloadCount, setReloadCount] = (0, import_react24.useState)(0);
4555
+ const [plans, setPlans] = (0, import_react25.useState)(null);
4556
+ const [error, setError] = (0, import_react25.useState)(false);
4557
+ const [busyPlanVersionId, setBusy] = (0, import_react25.useState)(null);
4558
+ const [lastError, setLastError] = (0, import_react25.useState)(null);
4559
+ const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react25.useState)(null);
4560
+ const [managedBy, setManagedBy] = (0, import_react25.useState)(null);
4561
+ const [reloadCount, setReloadCount] = (0, import_react25.useState)(0);
4480
4562
  const supplied = options.currentPlanVersionId;
4481
4563
  const discover = supplied === void 0;
4482
- (0, import_react24.useEffect)(() => {
4564
+ (0, import_react25.useEffect)(() => {
4483
4565
  let cancelled = false;
4484
4566
  client.billing.plans().then((result) => {
4485
4567
  if (!cancelled) {
@@ -4495,7 +4577,7 @@ function usePlans(options = {}) {
4495
4577
  cancelled = true;
4496
4578
  };
4497
4579
  }, [client, reloadCount]);
4498
- (0, import_react24.useEffect)(() => {
4580
+ (0, import_react25.useEffect)(() => {
4499
4581
  if (!token) {
4500
4582
  return;
4501
4583
  }
@@ -4512,11 +4594,11 @@ function usePlans(options = {}) {
4512
4594
  cancelled = true;
4513
4595
  };
4514
4596
  }, [client, token, discover, reloadCount]);
4515
- const reload = (0, import_react24.useCallback)(() => {
4597
+ const reload = (0, import_react25.useCallback)(() => {
4516
4598
  setError(false);
4517
4599
  setReloadCount((count) => count + 1);
4518
4600
  }, []);
4519
- const selectPlan = (0, import_react24.useCallback)(
4601
+ const selectPlan = (0, import_react25.useCallback)(
4520
4602
  async (plan) => {
4521
4603
  setLastError(null);
4522
4604
  if (managedBy) {
@@ -4584,7 +4666,7 @@ function usePlans(options = {}) {
4584
4666
  }
4585
4667
 
4586
4668
  // src/PricingTable.tsx
4587
- var import_jsx_runtime26 = require("react/jsx-runtime");
4669
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4588
4670
  function formatAmount(amount, currency) {
4589
4671
  if (amount === null) return "Free";
4590
4672
  const value = Number(amount);
@@ -4633,7 +4715,7 @@ function PricingTable({
4633
4715
  managedBy,
4634
4716
  selectPlan
4635
4717
  } = usePlans({ currentPlanVersionId });
4636
- const [scheduled, setScheduled] = (0, import_react25.useState)(null);
4718
+ const [scheduled, setScheduled] = (0, import_react26.useState)(null);
4637
4719
  async function choose(plan) {
4638
4720
  if (onSelectPlan) {
4639
4721
  await onSelectPlan(plan.planVersionId, plan);
@@ -4650,50 +4732,50 @@ function PricingTable({
4650
4732
  }
4651
4733
  }
4652
4734
  if (error) {
4653
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4735
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4654
4736
  }
4655
4737
  if (!plans) {
4656
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4738
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4657
4739
  }
4658
4740
  if (plans.length === 0) {
4659
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4741
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4660
4742
  }
4661
4743
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4662
4744
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4663
4745
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4664
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4746
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4665
4747
  managedBy ? (
4666
4748
  // A client company's plan comes from the firm that runs it. The table
4667
4749
  // still shows what is on offer, with the current plan marked, but
4668
4750
  // nothing here can be bought: it would grant this account nothing.
4669
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4751
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4670
4752
  "Your plan is provided by ",
4671
4753
  managedBy.name ?? "the organization that manages your account",
4672
4754
  ". Ask them to change it."
4673
4755
  ] })
4674
- ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4756
+ ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4675
4757
  plans.map((plan) => {
4676
4758
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4677
4759
  const isCurrent = current === plan.planVersionId;
4678
4760
  const featured = featuredPlanKey === plan.key;
4679
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4761
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4680
4762
  "div",
4681
4763
  {
4682
4764
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4683
4765
  children: [
4684
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-head", children: [
4685
- anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4686
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4687
- anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4766
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-plan-head", children: [
4767
+ anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4768
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4769
+ anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4688
4770
  ] }),
4689
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-pricing", children: [
4690
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4691
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4692
- anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4771
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-plan-pricing", children: [
4772
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4773
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4774
+ anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4693
4775
  ] }),
4694
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { className: "b316-plan-feature", children: [
4695
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: entitlement.featureName }),
4696
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4776
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("li", { className: "b316-plan-feature", children: [
4777
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: entitlement.featureName }),
4778
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4697
4779
  // A usage price on the feature makes the limit an
4698
4780
  // allowance billed past, not a ceiling — the same
4699
4781
  // rule `check()` applies (any non-FLAT price).
@@ -4702,7 +4784,7 @@ function PricingTable({
4702
4784
  ) ? `${entitlement.limit} included` : entitlement.limit
4703
4785
  ) })
4704
4786
  ] }, entitlement.featureId)) }),
4705
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4787
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4706
4788
  "button",
4707
4789
  {
4708
4790
  type: "button",
@@ -4722,13 +4804,101 @@ function PricingTable({
4722
4804
  ] });
4723
4805
  }
4724
4806
 
4807
+ // src/useAddons.ts
4808
+ var import_react27 = require("react");
4809
+ function codeOf(cause) {
4810
+ const reason = cause?.reason;
4811
+ return typeof reason === "string" ? reason : "request_failed";
4812
+ }
4813
+ function useAddons() {
4814
+ const { client, token } = useBase316();
4815
+ const [attached, setAttached] = (0, import_react27.useState)(null);
4816
+ const [available, setAvailable] = (0, import_react27.useState)(null);
4817
+ const [loading2, setLoading] = (0, import_react27.useState)(true);
4818
+ const [lastError, setLastError] = (0, import_react27.useState)(null);
4819
+ const [busy, setBusy] = (0, import_react27.useState)(null);
4820
+ const [reloadCount, setReloadCount] = (0, import_react27.useState)(0);
4821
+ (0, import_react27.useEffect)(() => {
4822
+ let cancelled = false;
4823
+ if (!token) {
4824
+ return;
4825
+ }
4826
+ client.billing.addonsForSubscription(token).then((result) => {
4827
+ if (!cancelled) {
4828
+ setAttached(result.attached);
4829
+ setAvailable(result.available);
4830
+ setLastError(null);
4831
+ }
4832
+ }).catch((cause) => {
4833
+ if (!cancelled) {
4834
+ setAttached(null);
4835
+ setAvailable(null);
4836
+ setLastError(codeOf(cause));
4837
+ }
4838
+ }).finally(() => {
4839
+ if (!cancelled) {
4840
+ setLoading(false);
4841
+ }
4842
+ });
4843
+ return () => {
4844
+ cancelled = true;
4845
+ };
4846
+ }, [client, token, reloadCount]);
4847
+ const reload = (0, import_react27.useCallback)(() => {
4848
+ setLoading(true);
4849
+ setReloadCount((count) => count + 1);
4850
+ }, []);
4851
+ const run = (0, import_react27.useCallback)(
4852
+ async (key, action) => {
4853
+ if (!token) {
4854
+ setLastError("needs_sign_in");
4855
+ return null;
4856
+ }
4857
+ setBusy(key);
4858
+ setLastError(null);
4859
+ try {
4860
+ const outcome = await action(token);
4861
+ reload();
4862
+ return outcome;
4863
+ } catch (cause) {
4864
+ setLastError(codeOf(cause));
4865
+ return null;
4866
+ } finally {
4867
+ setBusy(null);
4868
+ }
4869
+ },
4870
+ [token, reload]
4871
+ );
4872
+ return {
4873
+ attached,
4874
+ available,
4875
+ loading: Boolean(token) && loading2,
4876
+ lastError,
4877
+ busy,
4878
+ signedIn: Boolean(token),
4879
+ attach: (addonId, quantity) => run(
4880
+ addonId,
4881
+ (session) => client.billing.attachAddon(session, {
4882
+ addonId,
4883
+ ...quantity === void 0 ? {} : { quantity }
4884
+ })
4885
+ ),
4886
+ setQuantity: (attachmentId, quantity) => run(
4887
+ attachmentId,
4888
+ (session) => client.billing.setAddonQuantity(session, attachmentId, quantity)
4889
+ ),
4890
+ remove: (attachmentId) => run(attachmentId, (session) => client.billing.removeAddon(session, attachmentId)),
4891
+ reload
4892
+ };
4893
+ }
4894
+
4725
4895
  // src/DataTable.tsx
4726
4896
  var import_sdk9 = require("@base316/sdk");
4727
- var import_react29 = require("react");
4897
+ var import_react31 = require("react");
4728
4898
 
4729
4899
  // src/fields.tsx
4730
4900
  var import_sdk7 = require("@base316/sdk");
4731
- var import_jsx_runtime27 = require("react/jsx-runtime");
4901
+ var import_jsx_runtime28 = require("react/jsx-runtime");
4732
4902
  function formatNumber(value, fraction = 0) {
4733
4903
  const number = Number(value);
4734
4904
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4750,10 +4920,10 @@ function formatDuration(value) {
4750
4920
  }
4751
4921
  function FieldCell({ value, field, related }) {
4752
4922
  if (field.type === "RELATION") {
4753
- return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4923
+ return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4754
4924
  }
4755
4925
  if (value === null || value === void 0 || value === "") {
4756
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2014" });
4926
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: "\u2014" });
4757
4927
  }
4758
4928
  switch (field.type) {
4759
4929
  case "BOOLEAN":
@@ -4766,9 +4936,9 @@ function FieldCell({ value, field, related }) {
4766
4936
  return formatDuration(value);
4767
4937
  case "RATING": {
4768
4938
  const stars = Math.round(Number(value));
4769
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4939
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4770
4940
  "\u2605".repeat(stars),
4771
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4941
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4772
4942
  ] });
4773
4943
  }
4774
4944
  case "DATE":
@@ -4776,15 +4946,15 @@ function FieldCell({ value, field, related }) {
4776
4946
  case "DATETIME":
4777
4947
  return new Date(String(value)).toLocaleString();
4778
4948
  case "SELECT":
4779
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(value) });
4949
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-chip", children: String(value) });
4780
4950
  case "MULTISELECT":
4781
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4951
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4782
4952
  case "URL":
4783
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4953
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4784
4954
  case "EMAIL":
4785
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4955
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4786
4956
  case "PHONE":
4787
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4957
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4788
4958
  case "ADDRESS":
4789
4959
  return (0, import_sdk7.formatAddress)(value);
4790
4960
  case "ATTACHMENT": {
@@ -4796,7 +4966,7 @@ function FieldCell({ value, field, related }) {
4796
4966
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4797
4967
  }
4798
4968
  case "JSON":
4799
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4969
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4800
4970
  default:
4801
4971
  return String(value);
4802
4972
  }
@@ -4817,7 +4987,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4817
4987
  function control() {
4818
4988
  switch (field.type) {
4819
4989
  case "LONGTEXT":
4820
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4990
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4821
4991
  "textarea",
4822
4992
  {
4823
4993
  ...common,
@@ -4827,7 +4997,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4827
4997
  }
4828
4998
  );
4829
4999
  case "BOOLEAN":
4830
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5000
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4831
5001
  "input",
4832
5002
  {
4833
5003
  ...common,
@@ -4838,22 +5008,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4838
5008
  }
4839
5009
  );
4840
5010
  case "SELECT":
4841
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5011
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
4842
5012
  "select",
4843
5013
  {
4844
5014
  ...common,
4845
5015
  value: value === null || value === void 0 ? "" : String(value),
4846
5016
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4847
5017
  children: [
4848
- field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "", children: "\u2014" }),
4849
- (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: option, children: option }, option))
5018
+ field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: "", children: "\u2014" }),
5019
+ (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: option, children: option }, option))
4850
5020
  ]
4851
5021
  }
4852
5022
  );
4853
5023
  case "MULTISELECT": {
4854
5024
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4855
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-choice", children: [
4856
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5025
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-choice", children: [
5026
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4857
5027
  "input",
4858
5028
  {
4859
5029
  type: "checkbox",
@@ -4876,7 +5046,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4876
5046
  case "NUMBER":
4877
5047
  case "MONEY":
4878
5048
  case "PERCENT":
4879
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5049
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4880
5050
  "input",
4881
5051
  {
4882
5052
  ...common,
@@ -4887,7 +5057,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4887
5057
  }
4888
5058
  );
4889
5059
  case "RATING":
4890
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5060
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4891
5061
  "input",
4892
5062
  {
4893
5063
  ...common,
@@ -4901,8 +5071,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4901
5071
  );
4902
5072
  case "DURATION": {
4903
5073
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4904
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-suffixed", children: [
4905
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5074
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-suffixed", children: [
5075
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4906
5076
  "input",
4907
5077
  {
4908
5078
  ...common,
@@ -4912,11 +5082,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4912
5082
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4913
5083
  }
4914
5084
  ),
4915
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "minutes" })
5085
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: "minutes" })
4916
5086
  ] });
4917
5087
  }
4918
5088
  case "DATE":
4919
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5089
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4920
5090
  "input",
4921
5091
  {
4922
5092
  ...common,
@@ -4926,7 +5096,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4926
5096
  }
4927
5097
  );
4928
5098
  case "DATETIME":
4929
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5099
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4930
5100
  "input",
4931
5101
  {
4932
5102
  ...common,
@@ -4939,7 +5109,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4939
5109
  );
4940
5110
  case "ADDRESS": {
4941
5111
  const address = value ?? {};
4942
- const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5112
+ const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4943
5113
  "input",
4944
5114
  {
4945
5115
  className: "b316-input",
@@ -4951,7 +5121,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4951
5121
  },
4952
5122
  key
4953
5123
  );
4954
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-address", children: [
5124
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-address", children: [
4955
5125
  part("line1", "Address line 1"),
4956
5126
  part("line2", "Address line 2"),
4957
5127
  part("city", "City"),
@@ -4961,7 +5131,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4961
5131
  ] });
4962
5132
  }
4963
5133
  case "EMAIL":
4964
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5134
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4965
5135
  "input",
4966
5136
  {
4967
5137
  ...common,
@@ -4971,7 +5141,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4971
5141
  }
4972
5142
  );
4973
5143
  case "URL":
4974
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5144
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4975
5145
  "input",
4976
5146
  {
4977
5147
  ...common,
@@ -4981,7 +5151,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4981
5151
  }
4982
5152
  );
4983
5153
  case "PHONE":
4984
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5154
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4985
5155
  "input",
4986
5156
  {
4987
5157
  ...common,
@@ -4991,7 +5161,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4991
5161
  }
4992
5162
  );
4993
5163
  default:
4994
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5164
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4995
5165
  "input",
4996
5166
  {
4997
5167
  ...common,
@@ -5002,24 +5172,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
5002
5172
  );
5003
5173
  }
5004
5174
  }
5005
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-field", children: [
5006
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5175
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-field", children: [
5176
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5007
5177
  field.label,
5008
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5178
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5009
5179
  ] }),
5010
5180
  control(),
5011
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5012
- error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
5181
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5182
+ error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
5013
5183
  ] });
5014
5184
  }
5015
5185
 
5016
5186
  // src/RecordForm.tsx
5017
5187
  var import_sdk8 = require("@base316/sdk");
5018
- var import_react28 = require("react");
5188
+ var import_react30 = require("react");
5019
5189
 
5020
5190
  // src/RelationPicker.tsx
5021
- var import_react26 = require("react");
5022
- var import_jsx_runtime28 = require("react/jsx-runtime");
5191
+ var import_react28 = require("react");
5192
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5023
5193
  function RelationPicker({
5024
5194
  field,
5025
5195
  value,
@@ -5029,13 +5199,13 @@ function RelationPicker({
5029
5199
  tenant
5030
5200
  }) {
5031
5201
  const { client, token } = useBase316();
5032
- const [query, setQuery] = (0, import_react26.useState)("");
5033
- const [results, setResults] = (0, import_react26.useState)([]);
5034
- const [chosenTitle, setChosenTitle] = (0, import_react26.useState)(null);
5035
- const [open, setOpen] = (0, import_react26.useState)(false);
5202
+ const [query, setQuery] = (0, import_react28.useState)("");
5203
+ const [results, setResults] = (0, import_react28.useState)([]);
5204
+ const [chosenTitle, setChosenTitle] = (0, import_react28.useState)(null);
5205
+ const [open, setOpen] = (0, import_react28.useState)(false);
5036
5206
  const id = `b316-field-${field.key}`;
5037
- const box = (0, import_react26.useRef)(null);
5038
- (0, import_react26.useEffect)(() => {
5207
+ const box = (0, import_react28.useRef)(null);
5208
+ (0, import_react28.useEffect)(() => {
5039
5209
  if (!token || !value || !field.relationTo) {
5040
5210
  setChosenTitle(null);
5041
5211
  return;
@@ -5050,7 +5220,7 @@ function RelationPicker({
5050
5220
  cancelled = true;
5051
5221
  };
5052
5222
  }, [client, token, value, field.relationTo, tenant]);
5053
- (0, import_react26.useEffect)(() => {
5223
+ (0, import_react28.useEffect)(() => {
5054
5224
  if (!token || !field.relationTo || !open) {
5055
5225
  return;
5056
5226
  }
@@ -5076,7 +5246,7 @@ function RelationPicker({
5076
5246
  clearTimeout(timer);
5077
5247
  };
5078
5248
  }, [client, token, field.relationTo, query, open, tenant]);
5079
- (0, import_react26.useEffect)(() => {
5249
+ (0, import_react28.useEffect)(() => {
5080
5250
  if (!open || typeof document === "undefined") {
5081
5251
  return;
5082
5252
  }
@@ -5090,14 +5260,14 @@ function RelationPicker({
5090
5260
  document.removeEventListener("mousedown", onDocumentClick);
5091
5261
  };
5092
5262
  }, [open]);
5093
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-field", ref: box, children: [
5094
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5263
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-field", ref: box, children: [
5264
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5095
5265
  field.label,
5096
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5266
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5097
5267
  ] }),
5098
- value && !open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-relation-chosen", children: [
5099
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: chosenTitle ?? value }),
5100
- disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5268
+ value && !open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-relation-chosen", children: [
5269
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: chosenTitle ?? value }),
5270
+ disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5101
5271
  "button",
5102
5272
  {
5103
5273
  type: "button",
@@ -5109,7 +5279,7 @@ function RelationPicker({
5109
5279
  children: "Change"
5110
5280
  }
5111
5281
  ),
5112
- disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5282
+ disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5113
5283
  "button",
5114
5284
  {
5115
5285
  type: "button",
@@ -5119,8 +5289,8 @@ function RelationPicker({
5119
5289
  children: "Clear"
5120
5290
  }
5121
5291
  )
5122
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5123
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5292
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
5293
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5124
5294
  "input",
5125
5295
  {
5126
5296
  id,
@@ -5141,7 +5311,7 @@ function RelationPicker({
5141
5311
  }
5142
5312
  }
5143
5313
  ),
5144
- open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5314
+ open ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5145
5315
  "button",
5146
5316
  {
5147
5317
  type: "button",
@@ -5157,13 +5327,13 @@ function RelationPicker({
5157
5327
  }
5158
5328
  ) }, result.id)) }) : null
5159
5329
  ] }),
5160
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5161
- error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
5330
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5331
+ error ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
5162
5332
  ] });
5163
5333
  }
5164
5334
 
5165
5335
  // src/useCollection.ts
5166
- var import_react27 = require("react");
5336
+ var import_react29 = require("react");
5167
5337
  function fieldErrorFrom(cause) {
5168
5338
  const param = cause?.param;
5169
5339
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -5171,24 +5341,24 @@ function fieldErrorFrom(cause) {
5171
5341
  }
5172
5342
  function useCollection(collection, options = {}) {
5173
5343
  const { client, token } = useBase316();
5174
- const [schema, setSchema] = (0, import_react27.useState)(null);
5175
- const [records, setRecords] = (0, import_react27.useState)([]);
5176
- const [error, setError] = (0, import_react27.useState)(null);
5177
- const [loading, setLoading] = (0, import_react27.useState)(true);
5178
- const [total, setTotal] = (0, import_react27.useState)(0);
5179
- const [cursor, setCursor] = (0, import_react27.useState)(null);
5180
- const [reloadCount, setReloadCount] = (0, import_react27.useState)(0);
5181
- const [search, setSearch] = (0, import_react27.useState)("");
5182
- const [filters, setFilters] = (0, import_react27.useState)([]);
5183
- const [sort, setSort] = (0, import_react27.useState)(
5344
+ const [schema, setSchema] = (0, import_react29.useState)(null);
5345
+ const [records, setRecords] = (0, import_react29.useState)([]);
5346
+ const [error, setError] = (0, import_react29.useState)(null);
5347
+ const [loading2, setLoading] = (0, import_react29.useState)(true);
5348
+ const [total, setTotal] = (0, import_react29.useState)(0);
5349
+ const [cursor, setCursor] = (0, import_react29.useState)(null);
5350
+ const [reloadCount, setReloadCount] = (0, import_react29.useState)(0);
5351
+ const [search, setSearch] = (0, import_react29.useState)("");
5352
+ const [filters, setFilters] = (0, import_react29.useState)([]);
5353
+ const [sort, setSort] = (0, import_react29.useState)(
5184
5354
  options.sort ?? null
5185
5355
  );
5186
- const [fieldErrors, setFieldErrors] = (0, import_react27.useState)({});
5187
- const [saving, setSaving] = (0, import_react27.useState)(false);
5356
+ const [fieldErrors, setFieldErrors] = (0, import_react29.useState)({});
5357
+ const [saving, setSaving] = (0, import_react29.useState)(false);
5188
5358
  const { tenant, limit, recordId } = options;
5189
5359
  const fixedFilters = JSON.stringify(options.filters ?? []);
5190
- const scope = (0, import_react27.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
5191
- (0, import_react27.useEffect)(() => {
5360
+ const scope = (0, import_react29.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
5361
+ (0, import_react29.useEffect)(() => {
5192
5362
  if (!token) {
5193
5363
  return;
5194
5364
  }
@@ -5207,7 +5377,7 @@ function useCollection(collection, options = {}) {
5207
5377
  cancelled = true;
5208
5378
  };
5209
5379
  }, [client, token, collection, scope]);
5210
- (0, import_react27.useEffect)(() => {
5380
+ (0, import_react29.useEffect)(() => {
5211
5381
  if (!token || !schema) {
5212
5382
  return;
5213
5383
  }
@@ -5277,10 +5447,10 @@ function useCollection(collection, options = {}) {
5277
5447
  scope,
5278
5448
  reloadCount
5279
5449
  ]);
5280
- const reload = (0, import_react27.useCallback)(() => {
5450
+ const reload = (0, import_react29.useCallback)(() => {
5281
5451
  setReloadCount((count) => count + 1);
5282
5452
  }, []);
5283
- const loadMore = (0, import_react27.useCallback)(() => {
5453
+ const loadMore = (0, import_react29.useCallback)(() => {
5284
5454
  if (!token || !cursor) {
5285
5455
  return;
5286
5456
  }
@@ -5304,7 +5474,7 @@ function useCollection(collection, options = {}) {
5304
5474
  setLoading(false);
5305
5475
  });
5306
5476
  }, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
5307
- const toggleSort = (0, import_react27.useCallback)((field) => {
5477
+ const toggleSort = (0, import_react29.useCallback)((field) => {
5308
5478
  setSort((current) => {
5309
5479
  if (current?.field !== field) {
5310
5480
  return { field, direction: "asc" };
@@ -5312,7 +5482,7 @@ function useCollection(collection, options = {}) {
5312
5482
  return current.direction === "asc" ? { field, direction: "desc" } : null;
5313
5483
  });
5314
5484
  }, []);
5315
- const create = (0, import_react27.useCallback)(
5485
+ const create = (0, import_react29.useCallback)(
5316
5486
  async (fields) => {
5317
5487
  if (!token) {
5318
5488
  return null;
@@ -5332,7 +5502,7 @@ function useCollection(collection, options = {}) {
5332
5502
  },
5333
5503
  [client, token, collection, scope, reload]
5334
5504
  );
5335
- const update = (0, import_react27.useCallback)(
5505
+ const update = (0, import_react29.useCallback)(
5336
5506
  async (id, fields) => {
5337
5507
  if (!token) {
5338
5508
  return null;
@@ -5354,7 +5524,7 @@ function useCollection(collection, options = {}) {
5354
5524
  },
5355
5525
  [client, token, collection, scope]
5356
5526
  );
5357
- const remove = (0, import_react27.useCallback)(
5527
+ const remove = (0, import_react29.useCallback)(
5358
5528
  async (id) => {
5359
5529
  if (!token) {
5360
5530
  return false;
@@ -5377,7 +5547,7 @@ function useCollection(collection, options = {}) {
5377
5547
  return {
5378
5548
  schema,
5379
5549
  records,
5380
- loading,
5550
+ loading: loading2,
5381
5551
  error,
5382
5552
  total,
5383
5553
  hasMore: cursor !== null,
@@ -5399,7 +5569,7 @@ function useCollection(collection, options = {}) {
5399
5569
  }
5400
5570
 
5401
5571
  // src/RecordForm.tsx
5402
- var import_jsx_runtime29 = require("react/jsx-runtime");
5572
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5403
5573
  function RecordForm({
5404
5574
  collection,
5405
5575
  recordId,
@@ -5420,20 +5590,20 @@ function RecordForm({
5420
5590
  recordId
5421
5591
  }
5422
5592
  );
5423
- const [values, setValues] = (0, import_react28.useState)(defaults ?? {});
5424
- const [loaded, setLoaded] = (0, import_react28.useState)(!recordId);
5593
+ const [values, setValues] = (0, import_react30.useState)(defaults ?? {});
5594
+ const [loaded, setLoaded] = (0, import_react30.useState)(!recordId);
5425
5595
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
5426
- (0, import_react28.useEffect)(() => {
5596
+ (0, import_react30.useEffect)(() => {
5427
5597
  if (existing && !loaded) {
5428
5598
  setValues(existing.fields);
5429
5599
  setLoaded(true);
5430
5600
  }
5431
5601
  }, [existing, loaded]);
5432
5602
  if (error) {
5433
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5603
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5434
5604
  }
5435
5605
  if (!schema || !loaded) {
5436
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5606
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5437
5607
  }
5438
5608
  const editable = schema.fields.filter((field) => !(0, import_sdk8.specFor)(field).computed);
5439
5609
  async function submit(event) {
@@ -5443,11 +5613,11 @@ function RecordForm({
5443
5613
  onSaved?.(saved.id);
5444
5614
  }
5445
5615
  }
5446
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5447
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5448
- fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5616
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5617
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5618
+ fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5449
5619
  editable.map(
5450
- (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5620
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5451
5621
  RelationPicker,
5452
5622
  {
5453
5623
  field,
@@ -5458,7 +5628,7 @@ function RecordForm({
5458
5628
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5459
5629
  },
5460
5630
  field.key
5461
- ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5631
+ ) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5462
5632
  FieldInput,
5463
5633
  {
5464
5634
  field,
@@ -5470,15 +5640,15 @@ function RecordForm({
5470
5640
  field.key
5471
5641
  )
5472
5642
  ),
5473
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-form-actions", children: [
5474
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5475
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5643
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-form-actions", children: [
5644
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5645
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5476
5646
  ] })
5477
5647
  ] });
5478
5648
  }
5479
5649
 
5480
5650
  // src/DataTable.tsx
5481
- var import_jsx_runtime30 = require("react/jsx-runtime");
5651
+ var import_jsx_runtime31 = require("react/jsx-runtime");
5482
5652
  function DataTable({
5483
5653
  collection,
5484
5654
  columns,
@@ -5495,7 +5665,7 @@ function DataTable({
5495
5665
  const {
5496
5666
  schema,
5497
5667
  records,
5498
- loading,
5668
+ loading: loading2,
5499
5669
  error,
5500
5670
  total,
5501
5671
  hasMore,
@@ -5507,13 +5677,13 @@ function DataTable({
5507
5677
  loadMore,
5508
5678
  remove
5509
5679
  } = useCollection(collection, options);
5510
- const [editing, setEditing] = (0, import_react29.useState)(null);
5511
- const [removeFailed, setRemoveFailed] = (0, import_react29.useState)(null);
5680
+ const [editing, setEditing] = (0, import_react31.useState)(null);
5681
+ const [removeFailed, setRemoveFailed] = (0, import_react31.useState)(null);
5512
5682
  if (error) {
5513
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5683
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5514
5684
  }
5515
5685
  if (!schema) {
5516
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5686
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5517
5687
  }
5518
5688
  const shown = columns ? (
5519
5689
  // Ordered by what was asked for, not by the schema: a caller naming
@@ -5522,10 +5692,10 @@ function DataTable({
5522
5692
  ) : schema.fields;
5523
5693
  const searchable = schema.fields.some((field) => (0, import_sdk9.specFor)(field).capabilities.searchable);
5524
5694
  const writable = canWrite && !readOnly;
5525
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5526
- removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5527
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-bar", children: [
5528
- searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5695
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5696
+ removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5697
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-table-bar", children: [
5698
+ searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5529
5699
  "input",
5530
5700
  {
5531
5701
  type: "search",
@@ -5535,25 +5705,25 @@ function DataTable({
5535
5705
  value: search,
5536
5706
  onChange: (event) => setSearch(event.target.value)
5537
5707
  }
5538
- ) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {}),
5539
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-actions", children: [
5540
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "b316-muted", children: [
5708
+ ) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", {}),
5709
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-table-actions", children: [
5710
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "b316-muted", children: [
5541
5711
  total,
5542
5712
  " ",
5543
5713
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5544
5714
  ] }),
5545
- writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5715
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5546
5716
  "New ",
5547
5717
  schema.name.toLowerCase()
5548
5718
  ] }) : null
5549
5719
  ] })
5550
5720
  ] }),
5551
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
5552
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5721
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("table", { className: "b316-table", children: [
5722
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("tr", { children: [
5553
5723
  shown.map((field) => {
5554
5724
  const sortable = (0, import_sdk9.specFor)(field).capabilities.sortable;
5555
5725
  const active = sort?.field === field.key;
5556
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5726
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5557
5727
  "button",
5558
5728
  {
5559
5729
  type: "button",
@@ -5561,20 +5731,20 @@ function DataTable({
5561
5731
  onClick: () => toggleSort(field.key),
5562
5732
  children: [
5563
5733
  field.label,
5564
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5734
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5565
5735
  ]
5566
5736
  }
5567
5737
  ) : field.label }, field.key);
5568
5738
  }),
5569
- writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5739
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5570
5740
  ] }) }),
5571
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5741
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5572
5742
  "tr",
5573
5743
  {
5574
5744
  className: onSelect ? "b316-row-clickable" : void 0,
5575
5745
  onClick: onSelect ? () => onSelect(record) : void 0,
5576
5746
  children: [
5577
- shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5747
+ shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5578
5748
  FieldCell,
5579
5749
  {
5580
5750
  value: record.fields[field.key] ?? null,
@@ -5582,8 +5752,8 @@ function DataTable({
5582
5752
  related: record.related[field.key]
5583
5753
  }
5584
5754
  ) }, field.key)),
5585
- writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("td", { className: "b316-table-rowactions", children: [
5586
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5755
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("td", { className: "b316-table-rowactions", children: [
5756
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5587
5757
  "button",
5588
5758
  {
5589
5759
  type: "button",
@@ -5595,7 +5765,7 @@ function DataTable({
5595
5765
  children: "Edit"
5596
5766
  }
5597
5767
  ),
5598
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5768
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5599
5769
  ConfirmButton,
5600
5770
  {
5601
5771
  className: "b316-button-quiet b316-danger",
@@ -5619,10 +5789,10 @@ function DataTable({
5619
5789
  record.id
5620
5790
  )) })
5621
5791
  ] }) }),
5622
- records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5623
- loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5624
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5625
- editing ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5792
+ records.length === 0 && !loading2 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5793
+ loading2 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5794
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading2, children: "Load more" }) }) : null,
5795
+ editing ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5626
5796
  RecordForm,
5627
5797
  {
5628
5798
  collection,
@@ -5646,8 +5816,8 @@ function ariaSort(active, direction) {
5646
5816
 
5647
5817
  // src/Kanban.tsx
5648
5818
  var import_sdk10 = require("@base316/sdk");
5649
- var import_react30 = require("react");
5650
- var import_jsx_runtime31 = require("react/jsx-runtime");
5819
+ var import_react32 = require("react");
5820
+ var import_jsx_runtime32 = require("react/jsx-runtime");
5651
5821
  function Kanban({
5652
5822
  collection,
5653
5823
  groupBy,
@@ -5658,23 +5828,23 @@ function Kanban({
5658
5828
  style,
5659
5829
  ...options
5660
5830
  }) {
5661
- const { schema, records, loading, error, canWrite, update, total, hasMore, loadMore } = useCollection(collection, {
5831
+ const { schema, records, loading: loading2, error, canWrite, update, total, hasMore, loadMore } = useCollection(collection, {
5662
5832
  // A board shows everything at once by its nature — a column holding the
5663
5833
  // first twenty-five of two hundred is misleading rather than partial.
5664
5834
  limit: options.limit ?? 100,
5665
5835
  ...options
5666
5836
  });
5667
- const [dragging, setDragging] = (0, import_react30.useState)(null);
5668
- const [over, setOver] = (0, import_react30.useState)(null);
5837
+ const [dragging, setDragging] = (0, import_react32.useState)(null);
5838
+ const [over, setOver] = (0, import_react32.useState)(null);
5669
5839
  if (error) {
5670
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5840
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5671
5841
  }
5672
5842
  if (!schema) {
5673
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5843
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5674
5844
  }
5675
5845
  const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk10.defaultGroupFieldOf)(schema.fields);
5676
5846
  if (!field || !(0, import_sdk10.specFor)(field).capabilities.groupable) {
5677
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5847
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5678
5848
  }
5679
5849
  const columns = columnsFor(field);
5680
5850
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5691,12 +5861,12 @@ function Kanban({
5691
5861
  }
5692
5862
  await update(record.id, { [field.key]: value });
5693
5863
  }
5694
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5695
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5864
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5865
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5696
5866
  const inColumn = records.filter(
5697
5867
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5698
5868
  );
5699
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5869
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5700
5870
  "section",
5701
5871
  {
5702
5872
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5720,12 +5890,12 @@ function Kanban({
5720
5890
  setDragging(null);
5721
5891
  },
5722
5892
  children: [
5723
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("header", { className: "b316-board-head", children: [
5724
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-board-title", children: column.label }),
5725
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: inColumn.length })
5893
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("header", { className: "b316-board-head", children: [
5894
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-board-title", children: column.label }),
5895
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-muted", children: inColumn.length })
5726
5896
  ] }),
5727
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-cards", children: [
5728
- inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5897
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-board-cards", children: [
5898
+ inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5729
5899
  "article",
5730
5900
  {
5731
5901
  className: "b316-board-card",
@@ -5737,10 +5907,10 @@ function Kanban({
5737
5907
  },
5738
5908
  onClick: onSelect ? () => onSelect(record) : void 0,
5739
5909
  children: [
5740
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5741
- shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-card-field", children: [
5742
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: candidate.label }),
5743
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5910
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5911
+ shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-board-card-field", children: [
5912
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-muted", children: candidate.label }),
5913
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5744
5914
  FieldCell,
5745
5915
  {
5746
5916
  value: record.fields[candidate.key] ?? null,
@@ -5753,9 +5923,9 @@ function Kanban({
5753
5923
  // Dragging is not reachable by keyboard and is awkward on a
5754
5924
  // phone. This is the same action by other means, not a
5755
5925
  // lesser fallback.
5756
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "b316-board-move", children: [
5757
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: "Move to" }),
5758
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5926
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-board-move", children: [
5927
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-muted", children: "Move to" }),
5928
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5759
5929
  "select",
5760
5930
  {
5761
5931
  className: "b316-input",
@@ -5767,7 +5937,7 @@ function Kanban({
5767
5937
  );
5768
5938
  void move(record, chosen?.value ?? null);
5769
5939
  },
5770
- children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5940
+ children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5771
5941
  }
5772
5942
  )
5773
5943
  ] })
@@ -5776,14 +5946,14 @@ function Kanban({
5776
5946
  },
5777
5947
  record.id
5778
5948
  )),
5779
- inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5949
+ inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5780
5950
  ] })
5781
5951
  ]
5782
5952
  },
5783
5953
  String(column.value)
5784
5954
  );
5785
5955
  }) }),
5786
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5956
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading2, children: [
5787
5957
  "Showing ",
5788
5958
  records.length,
5789
5959
  " of ",
@@ -5805,8 +5975,8 @@ function columnsFor(field) {
5805
5975
 
5806
5976
  // src/Chart.tsx
5807
5977
  var import_sdk11 = require("@base316/sdk");
5808
- var import_react31 = require("react");
5809
- var import_jsx_runtime32 = require("react/jsx-runtime");
5978
+ var import_react33 = require("react");
5979
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5810
5980
  function Chart({
5811
5981
  collection,
5812
5982
  x,
@@ -5819,13 +5989,13 @@ function Chart({
5819
5989
  style,
5820
5990
  ...options
5821
5991
  }) {
5822
- const { schema, records, error, loading } = useCollection(collection, {
5992
+ const { schema, records, error, loading: loading2 } = useCollection(collection, {
5823
5993
  // A chart of one page is a chart of an arbitrary subset, which is worse
5824
5994
  // than no chart: it looks like an answer.
5825
5995
  limit: options.limit ?? 200,
5826
5996
  ...options
5827
5997
  });
5828
- const axis = (0, import_react31.useMemo)(() => {
5998
+ const axis = (0, import_react33.useMemo)(() => {
5829
5999
  if (!schema) {
5830
6000
  return null;
5831
6001
  }
@@ -5833,35 +6003,35 @@ function Chart({
5833
6003
  const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
5834
6004
  return chosen && (0, import_sdk11.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5835
6005
  }, [schema, x]);
5836
- const measure = (0, import_react31.useMemo)(() => {
6006
+ const measure = (0, import_react33.useMemo)(() => {
5837
6007
  if (!schema || !y) {
5838
6008
  return null;
5839
6009
  }
5840
6010
  const candidates = (0, import_sdk11.fieldsAggregatableBy)(schema.fields, aggregate);
5841
6011
  return candidates.find((field) => field.key === y) ?? null;
5842
6012
  }, [schema, y, aggregate]);
5843
- const buckets = (0, import_react31.useMemo)(
6013
+ const buckets = (0, import_react33.useMemo)(
5844
6014
  () => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
5845
6015
  [records, axis, measure, aggregate, bucket, y]
5846
6016
  );
5847
6017
  if (error) {
5848
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6018
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5849
6019
  }
5850
- if (!schema || loading) {
5851
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6020
+ if (!schema || loading2) {
6021
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5852
6022
  }
5853
6023
  if (!axis) {
5854
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
6024
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5855
6025
  }
5856
6026
  if (y && !measure) {
5857
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
6027
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5858
6028
  }
5859
6029
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5860
6030
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5861
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5862
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5863
- buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-chart-col", children: [
5864
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6031
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
6032
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
6033
+ buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-chart-col", children: [
6034
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5865
6035
  "div",
5866
6036
  {
5867
6037
  className: "b316-chart-bar",
@@ -5869,18 +6039,18 @@ function Chart({
5869
6039
  title: `${entry.label}: ${format(entry.value)}`
5870
6040
  }
5871
6041
  ),
5872
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-chart-label", children: entry.label })
6042
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-chart-label", children: entry.label })
5873
6043
  ] }, entry.key)) }),
5874
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("details", { className: "b316-chart-data", children: [
5875
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("summary", { children: "Values" }),
5876
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("table", { className: "b316-table", children: [
5877
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
5878
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: axis.label }),
5879
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
6044
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("details", { className: "b316-chart-data", children: [
6045
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("summary", { children: "Values" }),
6046
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("table", { className: "b316-table", children: [
6047
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("tr", { children: [
6048
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("th", { scope: "col", children: axis.label }),
6049
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
5880
6050
  ] }) }),
5881
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
5882
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: entry.label }),
5883
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: format(entry.value) })
6051
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("tr", { children: [
6052
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("td", { children: entry.label }),
6053
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("td", { children: format(entry.value) })
5884
6054
  ] }, entry.key)) })
5885
6055
  ] })
5886
6056
  ] })
@@ -5939,8 +6109,8 @@ function combine(values, aggregate) {
5939
6109
 
5940
6110
  // src/RecordDetail.tsx
5941
6111
  var import_sdk12 = require("@base316/sdk");
5942
- var import_react32 = require("react");
5943
- var import_jsx_runtime33 = require("react/jsx-runtime");
6112
+ var import_react34 = require("react");
6113
+ var import_jsx_runtime34 = require("react/jsx-runtime");
5944
6114
  function RecordDetail({
5945
6115
  collection,
5946
6116
  recordId,
@@ -5952,27 +6122,27 @@ function RecordDetail({
5952
6122
  className,
5953
6123
  style
5954
6124
  }) {
5955
- const { schema, records, canWrite, remove, loading, error } = useCollection(collection, {
6125
+ const { schema, records, canWrite, remove, loading: loading2, error } = useCollection(collection, {
5956
6126
  tenant,
5957
6127
  recordId
5958
6128
  });
5959
- const [editing, setEditing] = (0, import_react32.useState)(false);
6129
+ const [editing, setEditing] = (0, import_react34.useState)(false);
5960
6130
  const record = records.find((candidate) => candidate.id === recordId);
5961
6131
  if (error) {
5962
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6132
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5963
6133
  }
5964
- if (!schema || loading) {
5965
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6134
+ if (!schema || loading2) {
6135
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5966
6136
  }
5967
6137
  if (!record) {
5968
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card", className), style, children: [
6138
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cls("b316-card", className), style, children: [
5969
6139
  "That ",
5970
6140
  schema.name.toLowerCase(),
5971
6141
  " is not available."
5972
6142
  ] });
5973
6143
  }
5974
6144
  if (editing) {
5975
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6145
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5976
6146
  RecordForm,
5977
6147
  {
5978
6148
  collection,
@@ -5986,12 +6156,12 @@ function RecordDetail({
5986
6156
  );
5987
6157
  }
5988
6158
  const writable = canWrite && !readOnly;
5989
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5990
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-head", children: [
5991
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5992
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-actions", children: [
5993
- writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5994
- writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6159
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
6160
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-detail-head", children: [
6161
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
6162
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-detail-actions", children: [
6163
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
6164
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5995
6165
  ConfirmButton,
5996
6166
  {
5997
6167
  className: "b316-button-quiet b316-danger",
@@ -6004,15 +6174,15 @@ function RecordDetail({
6004
6174
  children: "Delete"
6005
6175
  }
6006
6176
  ) : null,
6007
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
6177
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
6008
6178
  ] })
6009
6179
  ] }),
6010
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-row", children: [
6011
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("dt", { className: "b316-label", children: [
6180
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-detail-row", children: [
6181
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("dt", { className: "b316-label", children: [
6012
6182
  field.label,
6013
- (0, import_sdk12.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
6183
+ (0, import_sdk12.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
6014
6184
  ] }),
6015
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6185
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6016
6186
  FieldCell,
6017
6187
  {
6018
6188
  value: record.fields[field.key] ?? null,
@@ -6026,8 +6196,8 @@ function RecordDetail({
6026
6196
  }
6027
6197
 
6028
6198
  // src/SubscriptionManager.tsx
6029
- var import_react33 = require("react");
6030
- var import_jsx_runtime34 = require("react/jsx-runtime");
6199
+ var import_react35 = require("react");
6200
+ var import_jsx_runtime35 = require("react/jsx-runtime");
6031
6201
  function statusLabel(status2) {
6032
6202
  const words = status2.toLowerCase().split("_");
6033
6203
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
@@ -6067,16 +6237,16 @@ function SubscriptionManager({
6067
6237
  style
6068
6238
  }) {
6069
6239
  const { client, token, loading: sessionLoading } = useBase316();
6070
- const [subscription, setSubscription] = (0, import_react33.useState)(null);
6071
- const [loading, setLoading] = (0, import_react33.useState)(true);
6072
- const [managedBy, setManagedBy] = (0, import_react33.useState)(null);
6073
- const [schedule, setSchedule] = (0, import_react33.useState)([]);
6074
- const [busy, setBusy] = (0, import_react33.useState)(false);
6075
- const [error, setError] = (0, import_react33.useState)(null);
6076
- const [step, setStep] = (0, import_react33.useState)({ kind: "idle" });
6077
- const [reason, setReason] = (0, import_react33.useState)(null);
6078
- const [comment, setComment] = (0, import_react33.useState)("");
6079
- const load = (0, import_react33.useCallback)(async () => {
6240
+ const [subscription, setSubscription] = (0, import_react35.useState)(null);
6241
+ const [loading2, setLoading] = (0, import_react35.useState)(true);
6242
+ const [managedBy, setManagedBy] = (0, import_react35.useState)(null);
6243
+ const [schedule, setSchedule] = (0, import_react35.useState)([]);
6244
+ const [busy, setBusy] = (0, import_react35.useState)(false);
6245
+ const [error, setError] = (0, import_react35.useState)(null);
6246
+ const [step, setStep] = (0, import_react35.useState)({ kind: "idle" });
6247
+ const [reason, setReason] = (0, import_react35.useState)(null);
6248
+ const [comment, setComment] = (0, import_react35.useState)("");
6249
+ const load = (0, import_react35.useCallback)(async () => {
6080
6250
  if (!token) {
6081
6251
  setSubscription(null);
6082
6252
  setLoading(false);
@@ -6094,7 +6264,7 @@ function SubscriptionManager({
6094
6264
  setLoading(false);
6095
6265
  }
6096
6266
  }, [client, token]);
6097
- (0, import_react33.useEffect)(() => {
6267
+ (0, import_react35.useEffect)(() => {
6098
6268
  void load();
6099
6269
  }, [load]);
6100
6270
  const act = async (change, failure) => {
@@ -6111,30 +6281,30 @@ function SubscriptionManager({
6111
6281
  setBusy(false);
6112
6282
  }
6113
6283
  };
6114
- if (sessionLoading || loading) {
6115
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6284
+ if (sessionLoading || loading2) {
6285
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6116
6286
  }
6117
6287
  if (!token) {
6118
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
6288
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
6119
6289
  }
6120
6290
  if (error) {
6121
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6291
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6122
6292
  }
6123
6293
  if (!subscription) {
6124
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
6294
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
6125
6295
  }
6126
6296
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
6127
6297
  const next = schedule[0] ?? null;
6128
6298
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
6129
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cls("b316-card", className), style, children: [
6130
- error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6131
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
6132
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
6299
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cls("b316-card", className), style, children: [
6300
+ error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6301
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
6302
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6133
6303
  statusLabel(subscription.status),
6134
6304
  " \xB7 ",
6135
6305
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
6136
6306
  ] }),
6137
- next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
6307
+ next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
6138
6308
  "Moves to ",
6139
6309
  next.plan.name,
6140
6310
  " on ",
@@ -6142,7 +6312,7 @@ function SubscriptionManager({
6142
6312
  ". You keep ",
6143
6313
  subscription.planVersion.plan.name,
6144
6314
  " until then.",
6145
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6315
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6146
6316
  "button",
6147
6317
  {
6148
6318
  type: "button",
@@ -6167,17 +6337,17 @@ function SubscriptionManager({
6167
6337
  }
6168
6338
  ) })
6169
6339
  ] }) : null,
6170
- managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
6340
+ managedBy ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6171
6341
  "Provided by ",
6172
6342
  managedBy.name ?? "the organization that manages your account",
6173
6343
  ". Ask them to change or cancel it."
6174
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6175
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
6344
+ ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6345
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6176
6346
  "This subscription will not renew. You keep access until ",
6177
6347
  renews,
6178
6348
  "."
6179
6349
  ] }),
6180
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6350
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6181
6351
  "button",
6182
6352
  {
6183
6353
  type: "button",
@@ -6187,14 +6357,14 @@ function SubscriptionManager({
6187
6357
  children: busy ? "Working\u2026" : "Resume subscription"
6188
6358
  }
6189
6359
  )
6190
- ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
6191
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
6192
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
6360
+ ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
6361
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
6362
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
6193
6363
  step.cancellation.offer,
6194
6364
  step.cancellation.currency
6195
6365
  )}.` }),
6196
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6197
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6366
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6367
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6198
6368
  "button",
6199
6369
  {
6200
6370
  type: "button",
@@ -6207,7 +6377,7 @@ function SubscriptionManager({
6207
6377
  children: busy ? "Working\u2026" : "Accept offer and stay"
6208
6378
  }
6209
6379
  ),
6210
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6380
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6211
6381
  "button",
6212
6382
  {
6213
6383
  type: "button",
@@ -6221,12 +6391,12 @@ function SubscriptionManager({
6221
6391
  }
6222
6392
  )
6223
6393
  ] }),
6224
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
6394
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6225
6395
  "If you cancel, you keep access until ",
6226
6396
  renews,
6227
6397
  "."
6228
6398
  ] })
6229
- ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
6399
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6230
6400
  "form",
6231
6401
  {
6232
6402
  style: { marginTop: 14 },
@@ -6246,15 +6416,15 @@ function SubscriptionManager({
6246
6416
  }, "Could not cancel. Try again.");
6247
6417
  },
6248
6418
  children: [
6249
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
6419
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6250
6420
  "You keep access until ",
6251
6421
  renews,
6252
6422
  ". It will not renew after that."
6253
6423
  ] }),
6254
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("fieldset", { className: "b316-fieldset", children: [
6255
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
6256
- REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
6257
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6424
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("fieldset", { className: "b316-fieldset", children: [
6425
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
6426
+ REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
6427
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6258
6428
  "input",
6259
6429
  {
6260
6430
  type: "radio",
@@ -6264,12 +6434,12 @@ function SubscriptionManager({
6264
6434
  onChange: () => setReason(option.value)
6265
6435
  }
6266
6436
  ),
6267
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: option.label })
6437
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: option.label })
6268
6438
  ] }, option.value))
6269
6439
  ] }),
6270
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { className: "b316-field", children: [
6271
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
6272
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6440
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6441
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
6442
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6273
6443
  "textarea",
6274
6444
  {
6275
6445
  className: "b316-input",
@@ -6280,9 +6450,9 @@ function SubscriptionManager({
6280
6450
  }
6281
6451
  )
6282
6452
  ] }),
6283
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6284
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
6285
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
6453
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6454
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
6455
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
6286
6456
  "button",
6287
6457
  {
6288
6458
  type: "button",
@@ -6298,7 +6468,7 @@ function SubscriptionManager({
6298
6468
  ] })
6299
6469
  ]
6300
6470
  }
6301
- ) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6471
+ ) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6302
6472
  "button",
6303
6473
  {
6304
6474
  type: "button",
@@ -6316,11 +6486,11 @@ function SubscriptionManager({
6316
6486
  }
6317
6487
 
6318
6488
  // src/BillingPortal.tsx
6319
- var import_react37 = require("react");
6489
+ var import_react39 = require("react");
6320
6490
 
6321
6491
  // src/CreditBalances.tsx
6322
- var import_react34 = require("react");
6323
- var import_jsx_runtime35 = require("react/jsx-runtime");
6492
+ var import_react36 = require("react");
6493
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6324
6494
  function units(value) {
6325
6495
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
6326
6496
  }
@@ -6355,10 +6525,10 @@ function Feature({
6355
6525
  }) {
6356
6526
  const { client, token } = useBase316();
6357
6527
  const setting = feature.autoRecharge;
6358
- const [busy, setBusy] = (0, import_react34.useState)(false);
6359
- const [error, setError] = (0, import_react34.useState)(null);
6360
- const [saved, setSaved] = (0, import_react34.useState)(null);
6361
- const [pack, setPack] = (0, import_react34.useState)(feature.packs[0]?.id ?? "");
6528
+ const [busy, setBusy] = (0, import_react36.useState)(false);
6529
+ const [error, setError] = (0, import_react36.useState)(null);
6530
+ const [saved, setSaved] = (0, import_react36.useState)(null);
6531
+ const [pack, setPack] = (0, import_react36.useState)(feature.packs[0]?.id ?? "");
6362
6532
  const unit = feature.unit ? ` ${feature.unit}` : "";
6363
6533
  const warning = status(feature);
6364
6534
  const buy = async () => {
@@ -6412,33 +6582,33 @@ function Feature({
6412
6582
  setBusy(false);
6413
6583
  }
6414
6584
  };
6415
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6416
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-label", children: feature.featureName }),
6417
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6418
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: units(feature.remaining) }),
6585
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6586
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: feature.featureName }),
6587
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6588
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("strong", { children: units(feature.remaining) }),
6419
6589
  unit,
6420
6590
  " left"
6421
6591
  ] }),
6422
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6592
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
6423
6593
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
6424
6594
  " ",
6425
6595
  "\xB7 ",
6426
6596
  units(feature.purchasedRemaining),
6427
6597
  " purchased"
6428
6598
  ] }),
6429
- warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6430
- error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6431
- saved ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6432
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6433
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6434
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6599
+ warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6600
+ error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6601
+ saved ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6602
+ managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6603
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6604
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6435
6605
  "select",
6436
6606
  {
6437
6607
  className: "b316-input",
6438
6608
  "aria-label": "Pack to buy",
6439
6609
  value: pack,
6440
6610
  onChange: (event) => setPack(event.target.value),
6441
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("option", { value: option.id, children: [
6611
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("option", { value: option.id, children: [
6442
6612
  option.name,
6443
6613
  " \u2014 ",
6444
6614
  units(option.units),
@@ -6447,7 +6617,7 @@ function Feature({
6447
6617
  ] }, option.id))
6448
6618
  }
6449
6619
  ),
6450
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6620
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6451
6621
  "button",
6452
6622
  {
6453
6623
  type: "button",
@@ -6458,19 +6628,19 @@ function Feature({
6458
6628
  }
6459
6629
  )
6460
6630
  ] }),
6461
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6462
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-checkbox", children: [
6463
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6631
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6632
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-checkbox", children: [
6633
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6464
6634
  " ",
6465
6635
  "Buy credits automatically when my balance runs low"
6466
6636
  ] }),
6467
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6468
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
6637
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-field", children: [
6638
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "b316-label", children: [
6469
6639
  "When fewer than this many",
6470
6640
  unit,
6471
6641
  " are left"
6472
6642
  ] }),
6473
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6643
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6474
6644
  "input",
6475
6645
  {
6476
6646
  className: "b316-input",
@@ -6481,21 +6651,21 @@ function Feature({
6481
6651
  }
6482
6652
  )
6483
6653
  ] }),
6484
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6485
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "Buy" }),
6486
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6654
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-field", children: [
6655
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "b316-label", children: "Buy" }),
6656
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6487
6657
  "select",
6488
6658
  {
6489
6659
  className: "b316-input",
6490
6660
  name: "creditPackId",
6491
6661
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
6492
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("option", { value: option.id, children: option.name }, option.id))
6662
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: option.id, children: option.name }, option.id))
6493
6663
  }
6494
6664
  )
6495
6665
  ] }),
6496
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6497
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6498
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6666
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-field", children: [
6667
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6668
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6499
6669
  "input",
6500
6670
  {
6501
6671
  className: "b316-input",
@@ -6505,13 +6675,13 @@ function Feature({
6505
6675
  }
6506
6676
  )
6507
6677
  ] }),
6508
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6509
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
6678
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-field", children: [
6679
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "b316-label", children: [
6510
6680
  "Spending at most (",
6511
6681
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
6512
6682
  ") a month"
6513
6683
  ] }),
6514
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6684
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6515
6685
  "input",
6516
6686
  {
6517
6687
  className: "b316-input",
@@ -6521,16 +6691,16 @@ function Feature({
6521
6691
  }
6522
6692
  )
6523
6693
  ] }),
6524
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6694
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6525
6695
  ] })
6526
6696
  ] })
6527
6697
  ] });
6528
6698
  }
6529
6699
  function CreditBalances({ onChange, className, style }) {
6530
6700
  const { client, token, loading: sessionLoading } = useBase316();
6531
- const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
6532
- const [version, setVersion] = (0, import_react34.useState)(0);
6533
- (0, import_react34.useEffect)(() => {
6701
+ const [state, setState] = (0, import_react36.useState)({ kind: "loading" });
6702
+ const [version, setVersion] = (0, import_react36.useState)(0);
6703
+ (0, import_react36.useEffect)(() => {
6534
6704
  if (!token) return;
6535
6705
  let cancelled = false;
6536
6706
  client.billing.credits(token).then((credits2) => {
@@ -6543,24 +6713,24 @@ function CreditBalances({ onChange, className, style }) {
6543
6713
  cancelled = true;
6544
6714
  };
6545
6715
  }, [client, token, version]);
6546
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
6716
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
6547
6717
  if (sessionLoading || !token || state.kind === "loading") return null;
6548
6718
  if (state.kind === "error") {
6549
6719
  return wrap(
6550
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6720
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6551
6721
  );
6552
6722
  }
6553
6723
  const { credits } = state;
6554
6724
  if (credits.features.length === 0) return null;
6555
6725
  return wrap(
6556
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6557
- credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6726
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6727
+ credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { className: "b316-muted", children: [
6558
6728
  "Credits for this account come from",
6559
6729
  " ",
6560
6730
  credits.managedBy.name ?? "the organization that manages it",
6561
6731
  ", which manages them."
6562
6732
  ] }) : null,
6563
- credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6733
+ credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6564
6734
  Feature,
6565
6735
  {
6566
6736
  feature,
@@ -6577,19 +6747,19 @@ function CreditBalances({ onChange, className, style }) {
6577
6747
  }
6578
6748
 
6579
6749
  // src/PaymentMethod.tsx
6580
- var import_react35 = require("react");
6581
- var import_jsx_runtime36 = require("react/jsx-runtime");
6750
+ var import_react37 = require("react");
6751
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6582
6752
  function brandName(brand) {
6583
6753
  if (!brand) return "Card";
6584
6754
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6585
6755
  }
6586
6756
  function PaymentMethod({ returnUrl, className, style }) {
6587
6757
  const { client, token, loading: sessionLoading } = useBase316();
6588
- const [state, setState] = (0, import_react35.useState)({ kind: "loading" });
6589
- const [busy, setBusy] = (0, import_react35.useState)(false);
6590
- const [error, setError] = (0, import_react35.useState)(null);
6591
- const [version, setVersion] = (0, import_react35.useState)(0);
6592
- (0, import_react35.useEffect)(() => {
6758
+ const [state, setState] = (0, import_react37.useState)({ kind: "loading" });
6759
+ const [busy, setBusy] = (0, import_react37.useState)(false);
6760
+ const [error, setError] = (0, import_react37.useState)(null);
6761
+ const [version, setVersion] = (0, import_react37.useState)(0);
6762
+ (0, import_react37.useEffect)(() => {
6593
6763
  if (!token) return;
6594
6764
  let cancelled = false;
6595
6765
  client.billing.paymentMethods(token).then((result) => {
@@ -6605,7 +6775,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6605
6775
  cancelled = true;
6606
6776
  };
6607
6777
  }, [client, token, version]);
6608
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6778
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6609
6779
  if (sessionLoading) return wrap("Loading\u2026");
6610
6780
  if (!token) return wrap("Sign in to manage your payment method.");
6611
6781
  switch (state.kind) {
@@ -6613,11 +6783,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6613
6783
  return wrap("Loading\u2026");
6614
6784
  case "error":
6615
6785
  return wrap(
6616
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6786
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6617
6787
  );
6618
6788
  case "managed":
6619
6789
  return wrap(
6620
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6790
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6621
6791
  );
6622
6792
  }
6623
6793
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6636,31 +6806,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6636
6806
  }
6637
6807
  };
6638
6808
  return wrap(
6639
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6640
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Payment method" }),
6641
- card ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6642
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6809
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
6810
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-label", children: "Payment method" }),
6811
+ card ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6812
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6643
6813
  brandName(card.brand),
6644
6814
  " ending ",
6645
6815
  card.last4 ?? "????"
6646
6816
  ] }),
6647
- card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
6817
+ card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6648
6818
  "Expires ",
6649
6819
  String(card.expMonth).padStart(2, "0"),
6650
6820
  "/",
6651
6821
  card.expYear
6652
6822
  ] }) : null
6653
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6654
- others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { marginTop: 12 }, children: [
6655
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6656
- others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6657
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
6823
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6824
+ others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 12 }, children: [
6825
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6826
+ others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6827
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
6658
6828
  brandName(saved.brand),
6659
6829
  " ending ",
6660
6830
  saved.last4 ?? "????"
6661
6831
  ] }),
6662
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
6663
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6832
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
6833
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6664
6834
  "button",
6665
6835
  {
6666
6836
  type: "button",
@@ -6674,7 +6844,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6674
6844
  }
6675
6845
  ),
6676
6846
  " ",
6677
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6847
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6678
6848
  "button",
6679
6849
  {
6680
6850
  type: "button",
@@ -6690,8 +6860,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6690
6860
  ] })
6691
6861
  ] }, saved.id))
6692
6862
  ] }) : null,
6693
- error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6694
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6863
+ error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6864
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6695
6865
  "button",
6696
6866
  {
6697
6867
  type: "button",
@@ -6720,8 +6890,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6720
6890
  }
6721
6891
 
6722
6892
  // src/PlanChangeReview.tsx
6723
- var import_react36 = require("react");
6724
- var import_jsx_runtime37 = require("react/jsx-runtime");
6893
+ var import_react38 = require("react");
6894
+ var import_jsx_runtime38 = require("react/jsx-runtime");
6725
6895
  function money5(amount, currency) {
6726
6896
  if (amount === null) return "\u2014";
6727
6897
  const value = Number(amount);
@@ -6754,12 +6924,12 @@ function PlanChangeReview({
6754
6924
  style
6755
6925
  }) {
6756
6926
  const { client, token } = useBase316();
6757
- const [timing, setTiming] = (0, import_react36.useState)(void 0);
6758
- const [preview, setPreview] = (0, import_react36.useState)(null);
6759
- const [error, setError] = (0, import_react36.useState)(null);
6760
- const [needsCard, setNeedsCard] = (0, import_react36.useState)(false);
6761
- const [busy, setBusy] = (0, import_react36.useState)(false);
6762
- (0, import_react36.useEffect)(() => {
6927
+ const [timing, setTiming] = (0, import_react38.useState)(void 0);
6928
+ const [preview, setPreview] = (0, import_react38.useState)(null);
6929
+ const [error, setError] = (0, import_react38.useState)(null);
6930
+ const [needsCard, setNeedsCard] = (0, import_react38.useState)(false);
6931
+ const [busy, setBusy] = (0, import_react38.useState)(false);
6932
+ (0, import_react38.useEffect)(() => {
6763
6933
  if (!token) return;
6764
6934
  let cancelled = false;
6765
6935
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6776,7 +6946,7 @@ function PlanChangeReview({
6776
6946
  cancelled = true;
6777
6947
  };
6778
6948
  }, [client, token, planVersionId, timing]);
6779
- const confirm = (0, import_react36.useCallback)(async () => {
6949
+ const confirm = (0, import_react38.useCallback)(async () => {
6780
6950
  if (!token || !preview) return;
6781
6951
  setBusy(true);
6782
6952
  setError(null);
@@ -6797,7 +6967,7 @@ function PlanChangeReview({
6797
6967
  setBusy(false);
6798
6968
  }
6799
6969
  }, [client, token, preview, planVersionId, onDone]);
6800
- const addCard = (0, import_react36.useCallback)(async () => {
6970
+ const addCard = (0, import_react38.useCallback)(async () => {
6801
6971
  if (onNeedsCard) {
6802
6972
  onNeedsCard();
6803
6973
  return;
@@ -6811,12 +6981,12 @@ function PlanChangeReview({
6811
6981
  setError("Cards cannot be added here right now.");
6812
6982
  }
6813
6983
  }, [client, token, onNeedsCard]);
6814
- const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6984
+ const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6815
6985
  if (error && !preview) {
6816
6986
  return card(
6817
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
6818
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6819
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6987
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
6988
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6989
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6820
6990
  ] })
6821
6991
  );
6822
6992
  }
@@ -6829,26 +6999,26 @@ function PlanChangeReview({
6829
6999
  const otherReason = preview.timings[other]?.reason ?? null;
6830
7000
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6831
7001
  return card(
6832
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
6833
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-plan-name", children: [
7002
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
7003
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-plan-name", children: [
6834
7004
  "Change to ",
6835
7005
  to.planName
6836
7006
  ] }),
6837
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
7007
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-muted", children: [
6838
7008
  "From ",
6839
7009
  from.planName
6840
7010
  ] }),
6841
- error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6842
- changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("table", { className: "b316-review-table", children: [
6843
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
6844
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: "Feature" }),
6845
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: from.planName }),
6846
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: to.planName })
7011
+ error ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
7012
+ changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("table", { className: "b316-review-table", children: [
7013
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { children: [
7014
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { children: "Feature" }),
7015
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { children: from.planName }),
7016
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { children: to.planName })
6847
7017
  ] }) }),
6848
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
6849
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: change.featureName }),
6850
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: limitText(change.before, change.type) }),
6851
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7018
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { children: [
7019
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { children: change.featureName }),
7020
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { children: limitText(change.before, change.type) }),
7021
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6852
7022
  "td",
6853
7023
  {
6854
7024
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6857,40 +7027,40 @@ function PlanChangeReview({
6857
7027
  )
6858
7028
  ] }, change.featureId)) })
6859
7029
  ] }),
6860
- preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
7030
+ preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("p", { children: [
6861
7031
  "The change happens now. Your trial carries on until ",
6862
7032
  day4(now.trialEndsAt),
6863
7033
  ", and nothing is charged before then."
6864
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6865
- Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6866
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
7034
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
7035
+ Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-row", children: [
7036
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "b316-muted", children: [
6867
7037
  "Credit for the unused part of ",
6868
7038
  from.planName
6869
7039
  ] }),
6870
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-num", children: [
7040
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "b316-num", children: [
6871
7041
  "\u2212",
6872
7042
  money5(now.credit, from.currency)
6873
7043
  ] })
6874
7044
  ] }) : null,
6875
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6876
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6877
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
7045
+ Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-row", children: [
7046
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
7047
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6878
7048
  ] }) : null,
6879
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6880
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
7049
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-row", children: [
7050
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "b316-muted", children: [
6881
7051
  to.planName,
6882
7052
  ", ",
6883
7053
  day4(now.newPeriod.start),
6884
7054
  " \u2013 ",
6885
7055
  day4(now.newPeriod.end)
6886
7056
  ] }),
6887
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
7057
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6888
7058
  ] }),
6889
- now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6890
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "Due now" }),
6891
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
7059
+ now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
7060
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: "Due now" }),
7061
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
6892
7062
  ] }) : null
6893
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
7063
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("p", { children: [
6894
7064
  "You keep ",
6895
7065
  from.planName,
6896
7066
  " until ",
@@ -6903,7 +7073,7 @@ function PlanChangeReview({
6903
7073
  preview.atPeriodEnd.nextInvoice.currency
6904
7074
  )}.` : ""
6905
7075
  ] }),
6906
- otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7076
+ otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6907
7077
  "button",
6908
7078
  {
6909
7079
  type: "button",
@@ -6914,12 +7084,12 @@ function PlanChangeReview({
6914
7084
  },
6915
7085
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6916
7086
  }
6917
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6918
- needsCard ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", role: "status", children: [
7087
+ ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
7088
+ needsCard ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-notice", role: "status", children: [
6919
7089
  "A card is needed for a change that is charged now.",
6920
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6921
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-review-actions", children: [
6922
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7090
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
7091
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "b316-review-actions", children: [
7092
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6923
7093
  "button",
6924
7094
  {
6925
7095
  type: "button",
@@ -6929,7 +7099,7 @@ function PlanChangeReview({
6929
7099
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6930
7100
  }
6931
7101
  ),
6932
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
7102
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6933
7103
  "Keep ",
6934
7104
  from.planName
6935
7105
  ] }) : null
@@ -6939,7 +7109,7 @@ function PlanChangeReview({
6939
7109
  }
6940
7110
 
6941
7111
  // src/BillingPortal.tsx
6942
- var import_jsx_runtime38 = require("react/jsx-runtime");
7112
+ var import_jsx_runtime39 = require("react/jsx-runtime");
6943
7113
  function BillingPortal({
6944
7114
  returnUrl,
6945
7115
  featuredPlanKey,
@@ -6949,12 +7119,12 @@ function BillingPortal({
6949
7119
  style
6950
7120
  }) {
6951
7121
  const { client, token, loading: sessionLoading } = useBase316();
6952
- const [overview, setOverview] = (0, import_react37.useState)(null);
6953
- const [failed, setFailed] = (0, import_react37.useState)(false);
6954
- const [version, setVersion] = (0, import_react37.useState)(0);
6955
- const [reviewing, setReviewing] = (0, import_react37.useState)(null);
6956
- const [notice, setNotice] = (0, import_react37.useState)(null);
6957
- (0, import_react37.useEffect)(() => {
7122
+ const [overview, setOverview] = (0, import_react39.useState)(null);
7123
+ const [failed, setFailed] = (0, import_react39.useState)(false);
7124
+ const [version, setVersion] = (0, import_react39.useState)(0);
7125
+ const [reviewing, setReviewing] = (0, import_react39.useState)(null);
7126
+ const [notice, setNotice] = (0, import_react39.useState)(null);
7127
+ (0, import_react39.useEffect)(() => {
6958
7128
  if (!token) return;
6959
7129
  let cancelled = false;
6960
7130
  client.billing.subscription(token).then((result) => {
@@ -6973,28 +7143,28 @@ function BillingPortal({
6973
7143
  cancelled = true;
6974
7144
  };
6975
7145
  }, [client, token, version]);
6976
- const refresh = (0, import_react37.useCallback)(() => {
7146
+ const refresh = (0, import_react39.useCallback)(() => {
6977
7147
  setNotice(null);
6978
7148
  setVersion((value) => value + 1);
6979
7149
  }, []);
6980
- const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6981
- if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6982
- if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
7150
+ const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
7151
+ if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
7152
+ if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6983
7153
  if (failed) {
6984
7154
  return shell(
6985
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
7155
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6986
7156
  );
6987
7157
  }
6988
- if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
7158
+ if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6989
7159
  const { subscription, managedBy, quantityPriced } = overview;
6990
7160
  const canChange = Boolean(subscription) && !managedBy;
6991
7161
  return shell(
6992
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
6993
- notice ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6994
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6995
- canChange ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6996
- canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6997
- reviewing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7162
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
7163
+ notice ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
7164
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
7165
+ canChange ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
7166
+ canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
7167
+ reviewing ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6998
7168
  PlanChangeReview,
6999
7169
  {
7000
7170
  planVersionId: reviewing,
@@ -7007,9 +7177,9 @@ function BillingPortal({
7007
7177
  );
7008
7178
  }
7009
7179
  }
7010
- ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("section", { children: [
7011
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
7012
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
7180
+ ) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("section", { children: [
7181
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
7182
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7013
7183
  PricingTable,
7014
7184
  {
7015
7185
  featuredPlanKey,
@@ -7021,17 +7191,17 @@ function BillingPortal({
7021
7191
  `plans-${version}`
7022
7192
  )
7023
7193
  ] }),
7024
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CreditBalances, {}, `credits-${version}`),
7025
- managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
7026
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Invoices, {}, `invoices-${version}`),
7027
- billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
7194
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CreditBalances, {}, `credits-${version}`),
7195
+ managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
7196
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Invoices, {}, `invoices-${version}`),
7197
+ billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
7028
7198
  ] })
7029
7199
  );
7030
7200
  }
7031
7201
 
7032
7202
  // src/ApiKeyManager.tsx
7033
- var import_react38 = require("react");
7034
- var import_jsx_runtime39 = require("react/jsx-runtime");
7203
+ var import_react40 = require("react");
7204
+ var import_jsx_runtime40 = require("react/jsx-runtime");
7035
7205
  function duration(seconds) {
7036
7206
  if (seconds % 3600 === 0) {
7037
7207
  return `${seconds / 3600}h`;
@@ -7048,17 +7218,17 @@ function ApiKeyManager({
7048
7218
  audience
7049
7219
  }) {
7050
7220
  const { client, token, loading: sessionLoading } = useBase316();
7051
- const [resources, setResources] = (0, import_react38.useState)([]);
7052
- const [credentials, setCredentials] = (0, import_react38.useState)([]);
7053
- const [loading, setLoading] = (0, import_react38.useState)(true);
7054
- const [busy, setBusy] = (0, import_react38.useState)(false);
7055
- const [error, setError] = (0, import_react38.useState)(null);
7056
- const [creating, setCreating] = (0, import_react38.useState)(false);
7057
- const [name, setName] = (0, import_react38.useState)("");
7058
- const [chosen, setChosen] = (0, import_react38.useState)([]);
7059
- const [resourceId, setResourceId] = (0, import_react38.useState)(null);
7060
- const [issued, setIssued] = (0, import_react38.useState)(null);
7061
- const load = (0, import_react38.useCallback)(async () => {
7221
+ const [resources, setResources] = (0, import_react40.useState)([]);
7222
+ const [credentials, setCredentials] = (0, import_react40.useState)([]);
7223
+ const [loading2, setLoading] = (0, import_react40.useState)(true);
7224
+ const [busy, setBusy] = (0, import_react40.useState)(false);
7225
+ const [error, setError] = (0, import_react40.useState)(null);
7226
+ const [creating, setCreating] = (0, import_react40.useState)(false);
7227
+ const [name, setName] = (0, import_react40.useState)("");
7228
+ const [chosen, setChosen] = (0, import_react40.useState)([]);
7229
+ const [resourceId, setResourceId] = (0, import_react40.useState)(null);
7230
+ const [issued, setIssued] = (0, import_react40.useState)(null);
7231
+ const load = (0, import_react40.useCallback)(async () => {
7062
7232
  if (!token) {
7063
7233
  setLoading(false);
7064
7234
  return;
@@ -7079,20 +7249,20 @@ function ApiKeyManager({
7079
7249
  setLoading(false);
7080
7250
  }
7081
7251
  }, [client, token, audience]);
7082
- (0, import_react38.useEffect)(() => {
7252
+ (0, import_react40.useEffect)(() => {
7083
7253
  void load();
7084
7254
  }, [load]);
7085
- if (sessionLoading || loading) {
7086
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
7255
+ if (sessionLoading || loading2) {
7256
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
7087
7257
  }
7088
7258
  if (!token) {
7089
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
7259
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
7090
7260
  }
7091
7261
  if (error) {
7092
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
7262
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
7093
7263
  }
7094
7264
  if (resources.length === 0) {
7095
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
7265
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
7096
7266
  }
7097
7267
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
7098
7268
  const reset = () => {
@@ -7101,37 +7271,37 @@ function ApiKeyManager({
7101
7271
  setChosen([]);
7102
7272
  setIssued(null);
7103
7273
  };
7104
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cls("b316-card", className), style, children: [
7105
- error ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
7106
- resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7274
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cls("b316-card", className), style, children: [
7275
+ error ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
7276
+ resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7107
7277
  "select",
7108
7278
  {
7109
7279
  className: "b316-input",
7110
7280
  value: resource.id,
7111
7281
  onChange: (event) => setResourceId(event.target.value),
7112
7282
  style: { marginBottom: 14 },
7113
- children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: item.id, children: item.name }, item.id))
7283
+ children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("option", { value: item.id, children: item.name }, item.id))
7114
7284
  }
7115
- ) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: resource.name }),
7116
- resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
7285
+ ) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-plan-name", children: resource.name }),
7286
+ resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "b316-muted", children: [
7117
7287
  resource.rateLimit.requestsPerWindow,
7118
7288
  " requests per",
7119
7289
  " ",
7120
7290
  duration(resource.rateLimit.windowSeconds),
7121
7291
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
7122
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
7123
- credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { className: "b316-list-item", children: [
7124
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
7125
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: credential.name }),
7126
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
7127
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: credential.clientId }),
7292
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
7293
+ credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("li", { className: "b316-list-item", children: [
7294
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
7295
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-plan-name", children: credential.name }),
7296
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "b316-muted", children: [
7297
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("code", { children: credential.clientId }),
7128
7298
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
7129
7299
  credential.disabled ? " \xB7 Disabled" : null
7130
7300
  ] }),
7131
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
7301
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
7132
7302
  ] }),
7133
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
7134
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7303
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
7304
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7135
7305
  "button",
7136
7306
  {
7137
7307
  type: "button",
@@ -7160,7 +7330,7 @@ function ApiKeyManager({
7160
7330
  children: "Rotate"
7161
7331
  }
7162
7332
  ),
7163
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7333
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7164
7334
  ConfirmButton,
7165
7335
  {
7166
7336
  className: "b316-button b316-button-secondary",
@@ -7184,11 +7354,11 @@ function ApiKeyManager({
7184
7354
  )
7185
7355
  ] })
7186
7356
  ] }, credential.clientId)) }),
7187
- issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
7188
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", { children: "Copy this now." }),
7357
+ issued ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
7358
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("strong", { children: "Copy this now." }),
7189
7359
  " It is shown once and cannot be retrieved again.",
7190
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
7191
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7360
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
7361
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7192
7362
  "button",
7193
7363
  {
7194
7364
  type: "button",
@@ -7201,7 +7371,7 @@ function ApiKeyManager({
7201
7371
  children: "Copy"
7202
7372
  }
7203
7373
  ),
7204
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7374
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7205
7375
  "button",
7206
7376
  {
7207
7377
  type: "button",
@@ -7212,8 +7382,8 @@ function ApiKeyManager({
7212
7382
  }
7213
7383
  )
7214
7384
  ] }) : null,
7215
- creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 14 }, children: [
7216
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7385
+ creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { style: { marginTop: 14 }, children: [
7386
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7217
7387
  "input",
7218
7388
  {
7219
7389
  className: "b316-input",
@@ -7222,9 +7392,9 @@ function ApiKeyManager({
7222
7392
  onChange: (event) => setName(event.target.value)
7223
7393
  }
7224
7394
  ),
7225
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 10 }, children: [
7226
- resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox", children: [
7227
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7395
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { style: { marginTop: 10 }, children: [
7396
+ resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "b316-checkbox", children: [
7397
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7228
7398
  "input",
7229
7399
  {
7230
7400
  type: "checkbox",
@@ -7234,19 +7404,19 @@ function ApiKeyManager({
7234
7404
  )
7235
7405
  }
7236
7406
  ),
7237
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
7238
- scope.description ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "b316-muted", children: [
7407
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("code", { children: scope.key }),
7408
+ scope.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "b316-muted", children: [
7239
7409
  " \u2014 ",
7240
7410
  scope.description
7241
7411
  ] }) : null
7242
7412
  ] }, scope.key)),
7243
- resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
7244
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "checkbox", disabled: true }),
7245
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
7246
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: " \u2014 not included in your plan" })
7413
+ resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
7414
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("input", { type: "checkbox", disabled: true }),
7415
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("code", { children: scope.key }),
7416
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { children: " \u2014 not included in your plan" })
7247
7417
  ] }, scope.key))
7248
7418
  ] }),
7249
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7419
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7250
7420
  "button",
7251
7421
  {
7252
7422
  type: "button",
@@ -7280,7 +7450,7 @@ function ApiKeyManager({
7280
7450
  children: "Create key"
7281
7451
  }
7282
7452
  ),
7283
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7453
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7284
7454
  "button",
7285
7455
  {
7286
7456
  type: "button",
@@ -7291,7 +7461,7 @@ function ApiKeyManager({
7291
7461
  }
7292
7462
  )
7293
7463
  ] }) : null,
7294
- !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7464
+ !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
7295
7465
  "button",
7296
7466
  {
7297
7467
  type: "button",
@@ -7333,12 +7503,12 @@ var MANIFEST = [
7333
7503
  },
7334
7504
  {
7335
7505
  name: "appearance",
7336
- summary: "Colours, radius and font as tokens. Restyles everything at once.",
7506
+ summary: "Colors, radius and font as tokens. Restyles everything at once.",
7337
7507
  required: false
7338
7508
  },
7339
7509
  {
7340
7510
  name: "tenant",
7341
- summary: "White-label everything inside for one tenant \u2014 `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and colours on the screens it runs its clients on; its own branding, then its parent's, then the environment's. Change it when the user switches team.",
7511
+ summary: "White-label everything inside for one tenant \u2014 `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and colors on the screens it runs its clients on; its own branding, then its parent's, then the environment's. Change it when the user switches team.",
7342
7512
  required: false
7343
7513
  },
7344
7514
  ...appearance
@@ -7407,7 +7577,7 @@ var MANIFEST = [
7407
7577
  { name: "labels", summary: "Wording for the form, for translation.", required: false },
7408
7578
  {
7409
7579
  name: "secondFactorLabels",
7410
- summary: "Wording for the second-factor step (code box, or enrolment when the environment requires a factor and the user has none), for translation. English when omitted.",
7580
+ summary: "Wording for the second-factor step (code box, or enrollment when the environment requires a factor and the user has none), for translation. English when omitted.",
7411
7581
  required: false
7412
7582
  },
7413
7583
  ...appearance
@@ -7782,10 +7952,20 @@ var MANIFEST = [
7782
7952
  props: [],
7783
7953
  seeAlso: ["PricingTable"]
7784
7954
  },
7955
+ {
7956
+ name: "useAddons",
7957
+ kind: "hook",
7958
+ summary: "The signed-in user's addons and the ones on sale for their plan, with buy, resize and remove \u2014 settled by the API (more now and charged for the rest of the period, fewer at the period end). No markup.",
7959
+ useWhen: "You sell extras on top of a plan (more apps, seats, storage) as self-serve addons.",
7960
+ requires: ["session"],
7961
+ props: [],
7962
+ whenUnmet: "Loads nothing without a session; `lastError` carries the API's code.",
7963
+ seeAlso: ["usePlans", "SubscriptionManager"]
7964
+ },
7785
7965
  {
7786
7966
  name: "SubscriptionManager",
7787
7967
  kind: "component",
7788
- summary: "The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end \u2014 asking why, and showing the environment's retention offer when it makes one \u2014 and resuming a cancelled one.",
7968
+ summary: "The current plan, its renewal date, a scheduled plan change with its undo, canceling at the period end \u2014 asking why, and showing the environment's retention offer when it makes one \u2014 and resuming a canceled one.",
7789
7969
  useWhen: "A billing settings page.",
7790
7970
  requires: ["session"],
7791
7971
  props: [
@@ -8066,7 +8246,7 @@ var MANIFEST = [
8066
8246
  {
8067
8247
  name: "Chart",
8068
8248
  kind: "component",
8069
- summary: "Records over time, counted or totalled.",
8249
+ summary: "Records over time, counted or totaled.",
8070
8250
  useWhen: "The question is how many or how much, by day, week or month.",
8071
8251
  requires: ["session", "collection"],
8072
8252
  bindsToCollection: true,
@@ -8270,6 +8450,7 @@ function componentsRequiring(requirement) {
8270
8450
  VerifyEmail,
8271
8451
  componentsRequiring,
8272
8452
  describeComponent,
8453
+ useAddons,
8273
8454
  useBase316,
8274
8455
  useCollection,
8275
8456
  usePaymentLink,