@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/CHANGELOG.md +33 -0
- package/README.md +3 -3
- package/dist/index.cjs +1018 -837
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +748 -568
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +20 -5
- package/dist/src/CaptchaWidget.d.ts +22 -0
- package/dist/src/CaptchaWidget.d.ts.map +1 -0
- package/dist/src/SecondFactorStep.d.ts +2 -2
- package/dist/src/SignIn.d.ts +1 -1
- package/dist/src/SignUp.d.ts +2 -0
- package/dist/src/SignUp.d.ts.map +1 -1
- package/dist/src/SocialButtons.d.ts +1 -1
- package/dist/src/SocialSignIn.d.ts +1 -1
- package/dist/src/TeamMembers.d.ts +1 -1
- package/dist/src/TwoFactorManager.d.ts +1 -1
- package/dist/src/appearance.d.ts +4 -4
- package/dist/src/appearance.d.ts.map +1 -1
- package/dist/src/manifest.d.ts +1 -1
- package/dist/src/manifest.d.ts.map +1 -1
- package/dist/src/provider.d.ts +3 -3
- package/dist/src/provider.d.ts.map +1 -1
- package/dist/src/useAddons.d.ts +29 -0
- package/dist/src/useAddons.d.ts.map +1 -0
- package/dist/src/usePaymentLink.d.ts +1 -1
- package/package.json +2 -2
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
|
|
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
|
|
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 [
|
|
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,
|
|
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
|
|
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,
|
|
2765
|
-
const [email, setEmail] = (0,
|
|
2766
|
-
const [password, setPassword] = (0,
|
|
2767
|
-
const [error, setError] = (0,
|
|
2768
|
-
const [busy, setBusy] = (0,
|
|
2769
|
-
const [policy, setPolicy] = (0,
|
|
2770
|
-
const [pending, setPending] = (0,
|
|
2771
|
-
const [confirmEmail, setConfirmEmail] = (0,
|
|
2772
|
-
const [urlInvitation, setUrlInvitation] = (0,
|
|
2773
|
-
const [loaded, setLoaded] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2860
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
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,
|
|
2966
|
+
offered.password ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-divider", children: labels.or }) : null
|
|
2893
2967
|
] }) : null,
|
|
2894
|
-
preview ? /* @__PURE__ */ (0,
|
|
2895
|
-
error ? /* @__PURE__ */ (0,
|
|
2896
|
-
offered.password || socialOptions.length === 0 ? /* @__PURE__ */ (0,
|
|
2897
|
-
/* @__PURE__ */ (0,
|
|
2898
|
-
/* @__PURE__ */ (0,
|
|
2899
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2911
|
-
/* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
2926
|
-
/* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
3032
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2951
3033
|
function UserProfile({ className, style }) {
|
|
2952
|
-
const { session, loading, signOut } = useBase316();
|
|
2953
|
-
if (
|
|
2954
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
2961
|
-
/* @__PURE__ */ (0,
|
|
2962
|
-
/* @__PURE__ */ (0,
|
|
2963
|
-
user.name && user.email ? /* @__PURE__ */ (0,
|
|
2964
|
-
user.emailVerified === false ? /* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3062
|
+
var import_react12 = require("react");
|
|
2981
3063
|
|
|
2982
3064
|
// src/confirm.tsx
|
|
2983
|
-
var
|
|
2984
|
-
var
|
|
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,
|
|
2995
|
-
const confirmRef = (0,
|
|
2996
|
-
(0,
|
|
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,
|
|
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,
|
|
3020
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
3056
|
-
const [busy, setBusy] = (0,
|
|
3057
|
-
const [error, setError] = (0,
|
|
3058
|
-
const [name, setName] = (0,
|
|
3059
|
-
const [supported, setSupported] = (0,
|
|
3060
|
-
const load = (0,
|
|
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,
|
|
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,
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3111
|
-
/* @__PURE__ */ (0,
|
|
3112
|
-
passkeys === null ? /* @__PURE__ */ (0,
|
|
3113
|
-
/* @__PURE__ */ (0,
|
|
3114
|
-
/* @__PURE__ */ (0,
|
|
3115
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3132
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3152
|
-
var
|
|
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,
|
|
3171
|
-
const [error, setError] = (0,
|
|
3172
|
-
const [busy, setBusy] = (0,
|
|
3173
|
-
const load = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
3207
|
-
/* @__PURE__ */ (0,
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3209
|
-
sessions.length > 1 ? /* @__PURE__ */ (0,
|
|
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,
|
|
3212
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "b316-chip", children: " Support access" })
|
|
3217
3299
|
) : null
|
|
3218
3300
|
] }),
|
|
3219
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3231
|
-
var
|
|
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,
|
|
3240
|
-
const [request, setRequest] = (0,
|
|
3241
|
-
const [decided, setDecided] = (0,
|
|
3242
|
-
const [error, setError] = (0,
|
|
3243
|
-
const [busy, setBusy] = (0,
|
|
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,
|
|
3277
|
-
/* @__PURE__ */ (0,
|
|
3278
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3283
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3292
|
-
error ? /* @__PURE__ */ (0,
|
|
3293
|
-
/* @__PURE__ */ (0,
|
|
3294
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3318
|
-
/* @__PURE__ */ (0,
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
3320
|
-
error ? /* @__PURE__ */ (0,
|
|
3321
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3340
|
-
var
|
|
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,
|
|
3349
|
-
const [typed, setTyped] = (0,
|
|
3350
|
-
const [error, setError] = (0,
|
|
3351
|
-
const [busy, setBusy] = (0,
|
|
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,
|
|
3387
|
-
/* @__PURE__ */ (0,
|
|
3388
|
-
error ? /* @__PURE__ */ (0,
|
|
3389
|
-
/* @__PURE__ */ (0,
|
|
3390
|
-
/* @__PURE__ */ (0,
|
|
3391
|
-
/* @__PURE__ */ (0,
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3397
|
-
/* @__PURE__ */ (0,
|
|
3398
|
-
/* @__PURE__ */ (0,
|
|
3399
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3413
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3429
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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
|
|
3462
|
-
var
|
|
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,
|
|
3569
|
+
const { path, modules } = (0, import_react16.useMemo)(() => qrPath(value), [value]);
|
|
3488
3570
|
const extent = modules + QUIET_ZONE * 2;
|
|
3489
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
3502
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
3523
|
-
const [on, setOn] = (0,
|
|
3524
|
-
const [code, setCode] = (0,
|
|
3525
|
-
const [phone, setPhone] = (0,
|
|
3526
|
-
const [error, setError] = (0,
|
|
3527
|
-
const [busy, setBusy] = (0,
|
|
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,
|
|
3606
|
-
/* @__PURE__ */ (0,
|
|
3607
|
-
error ? /* @__PURE__ */ (0,
|
|
3608
|
-
stage.name === "saved" ? /* @__PURE__ */ (0,
|
|
3609
|
-
/* @__PURE__ */ (0,
|
|
3610
|
-
/* @__PURE__ */ (0,
|
|
3611
|
-
/* @__PURE__ */ (0,
|
|
3612
|
-
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0,
|
|
3613
|
-
/* @__PURE__ */ (0,
|
|
3614
|
-
/* @__PURE__ */ (0,
|
|
3615
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3628
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3640
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3658
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3679
|
-
/* @__PURE__ */ (0,
|
|
3680
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3689
|
-
/* @__PURE__ */ (0,
|
|
3690
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3693
|
-
/* @__PURE__ */ (0,
|
|
3694
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3706
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3727
|
-
/* @__PURE__ */ (0,
|
|
3728
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3739
|
-
/* @__PURE__ */ (0,
|
|
3740
|
-
/* @__PURE__ */ (0,
|
|
3741
|
-
/* @__PURE__ */ (0,
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3769
|
-
var
|
|
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,
|
|
3773
|
-
const [sent, setSent] = (0,
|
|
3774
|
-
const [busy, setBusy] = (0,
|
|
3775
|
-
const [error, setError] = (0,
|
|
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,
|
|
3792
|
-
/* @__PURE__ */ (0,
|
|
3793
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
3802
|
-
/* @__PURE__ */ (0,
|
|
3803
|
-
error ? /* @__PURE__ */ (0,
|
|
3804
|
-
/* @__PURE__ */ (0,
|
|
3805
|
-
/* @__PURE__ */ (0,
|
|
3806
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3820
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
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
|
|
3826
|
-
var
|
|
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,
|
|
3836
|
-
const [password, setPassword] = (0,
|
|
3837
|
-
const [confirmation, setConfirmation] = (0,
|
|
3838
|
-
const [done, setDone] = (0,
|
|
3839
|
-
const [busy, setBusy] = (0,
|
|
3840
|
-
const [error, setError] = (0,
|
|
3841
|
-
(0,
|
|
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,
|
|
3877
|
-
/* @__PURE__ */ (0,
|
|
3878
|
-
/* @__PURE__ */ (0,
|
|
3879
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
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,
|
|
3884
|
-
/* @__PURE__ */ (0,
|
|
3885
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3889
|
-
/* @__PURE__ */ (0,
|
|
3890
|
-
error ? /* @__PURE__ */ (0,
|
|
3891
|
-
/* @__PURE__ */ (0,
|
|
3892
|
-
/* @__PURE__ */ (0,
|
|
3893
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
3907
|
-
/* @__PURE__ */ (0,
|
|
3908
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
3927
|
-
var
|
|
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,
|
|
3937
|
-
const spent = (0,
|
|
3938
|
-
(0,
|
|
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,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
3967
|
-
continueUrl ? /* @__PURE__ */ (0,
|
|
3968
|
-
] }) : state === "failed" ? /* @__PURE__ */ (0,
|
|
3969
|
-
/* @__PURE__ */ (0,
|
|
3970
|
-
/* @__PURE__ */ (0,
|
|
3971
|
-
] }) : state === "missing" ? /* @__PURE__ */ (0,
|
|
3972
|
-
/* @__PURE__ */ (0,
|
|
3973
|
-
/* @__PURE__ */ (0,
|
|
3974
|
-
] }) : /* @__PURE__ */ (0,
|
|
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
|
|
3979
|
-
var
|
|
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,
|
|
3990
|
-
const [members, setMembers] = (0,
|
|
3991
|
-
const [invitations, setInvitations] = (0,
|
|
3992
|
-
const [email, setEmail] = (0,
|
|
3993
|
-
const [busy, setBusy] = (0,
|
|
3994
|
-
const [error, setError] = (0,
|
|
3995
|
-
const [copied, setCopied] = (0,
|
|
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,
|
|
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,
|
|
4007
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
4092
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4104
|
-
/* @__PURE__ */ (0,
|
|
4105
|
-
/* @__PURE__ */ (0,
|
|
4106
|
-
/* @__PURE__ */ (0,
|
|
4107
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4113
|
-
/* @__PURE__ */ (0,
|
|
4114
|
-
canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0,
|
|
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,
|
|
4127
|
-
/* @__PURE__ */ (0,
|
|
4128
|
-
/* @__PURE__ */ (0,
|
|
4129
|
-
/* @__PURE__ */ (0,
|
|
4130
|
-
/* @__PURE__ */ (0,
|
|
4131
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4150
|
-
/* @__PURE__ */ (0,
|
|
4151
|
-
/* @__PURE__ */ (0,
|
|
4152
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4168
|
-
/* @__PURE__ */ (0,
|
|
4169
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
4176
|
-
var
|
|
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,
|
|
4196
|
-
const [preview, setPreview] = (0,
|
|
4197
|
-
const [state, setState] = (0,
|
|
4198
|
-
const [error, setError] = (0,
|
|
4199
|
-
const [busy, setBusy] = (0,
|
|
4200
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
4247
|
-
/* @__PURE__ */ (0,
|
|
4248
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4259
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4270
|
-
!session ? /* @__PURE__ */ (0,
|
|
4271
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4277
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
4278
|
-
signUpUrl ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
4304
|
-
var
|
|
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,
|
|
4337
|
-
const stripeRef = (0,
|
|
4338
|
-
const elementsRef = (0,
|
|
4339
|
-
const [ready, setReady] = (0,
|
|
4340
|
-
const [paying, setPaying] = (0,
|
|
4341
|
-
const [done, setDone] = (0,
|
|
4342
|
-
const [error, setError] = (0,
|
|
4343
|
-
(0,
|
|
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,
|
|
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,
|
|
4399
|
-
error ? /* @__PURE__ */ (0,
|
|
4400
|
-
/* @__PURE__ */ (0,
|
|
4401
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
4415
|
-
const onPaidRef = (0,
|
|
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,
|
|
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
|
|
4548
|
+
var import_react26 = require("react");
|
|
4467
4549
|
|
|
4468
4550
|
// src/usePlans.ts
|
|
4469
|
-
var
|
|
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,
|
|
4474
|
-
const [error, setError] = (0,
|
|
4475
|
-
const [busyPlanVersionId, setBusy] = (0,
|
|
4476
|
-
const [lastError, setLastError] = (0,
|
|
4477
|
-
const [ownPlanVersionId, setOwnPlanVersionId] = (0,
|
|
4478
|
-
const [managedBy, setManagedBy] = (0,
|
|
4479
|
-
const [reloadCount, setReloadCount] = (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,
|
|
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,
|
|
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,
|
|
4597
|
+
const reload = (0, import_react25.useCallback)(() => {
|
|
4516
4598
|
setError(false);
|
|
4517
4599
|
setReloadCount((count) => count + 1);
|
|
4518
4600
|
}, []);
|
|
4519
|
-
const selectPlan = (0,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
4685
|
-
anyFeatured ? /* @__PURE__ */ (0,
|
|
4686
|
-
/* @__PURE__ */ (0,
|
|
4687
|
-
anyDescription ? /* @__PURE__ */ (0,
|
|
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,
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
4691
|
-
/* @__PURE__ */ (0,
|
|
4692
|
-
anyTrial ? /* @__PURE__ */ (0,
|
|
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,
|
|
4695
|
-
/* @__PURE__ */ (0,
|
|
4696
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
4897
|
+
var import_react31 = require("react");
|
|
4728
4898
|
|
|
4729
4899
|
// src/fields.tsx
|
|
4730
4900
|
var import_sdk7 = require("@base316/sdk");
|
|
4731
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
4939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
|
|
4770
4940
|
"\u2605".repeat(stars),
|
|
4771
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
4949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-chip", children: String(value) });
|
|
4780
4950
|
case "MULTISELECT":
|
|
4781
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
4955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
|
|
4786
4956
|
case "PHONE":
|
|
4787
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
4849
|
-
(field.options ?? []).map((option) => /* @__PURE__ */ (0,
|
|
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,
|
|
4856
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
4905
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
5006
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5012
|
-
error ? /* @__PURE__ */ (0,
|
|
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
|
|
5188
|
+
var import_react30 = require("react");
|
|
5019
5189
|
|
|
5020
5190
|
// src/RelationPicker.tsx
|
|
5021
|
-
var
|
|
5022
|
-
var
|
|
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,
|
|
5033
|
-
const [results, setResults] = (0,
|
|
5034
|
-
const [chosenTitle, setChosenTitle] = (0,
|
|
5035
|
-
const [open, setOpen] = (0,
|
|
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,
|
|
5038
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
5094
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
5266
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
5097
5267
|
] }),
|
|
5098
|
-
value && !open ? /* @__PURE__ */ (0,
|
|
5099
|
-
/* @__PURE__ */ (0,
|
|
5100
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5123
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5161
|
-
error ? /* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
5175
|
-
const [records, setRecords] = (0,
|
|
5176
|
-
const [error, setError] = (0,
|
|
5177
|
-
const [
|
|
5178
|
-
const [total, setTotal] = (0,
|
|
5179
|
-
const [cursor, setCursor] = (0,
|
|
5180
|
-
const [reloadCount, setReloadCount] = (0,
|
|
5181
|
-
const [search, setSearch] = (0,
|
|
5182
|
-
const [filters, setFilters] = (0,
|
|
5183
|
-
const [sort, setSort] = (0,
|
|
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,
|
|
5187
|
-
const [saving, setSaving] = (0,
|
|
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,
|
|
5191
|
-
(0,
|
|
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,
|
|
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,
|
|
5450
|
+
const reload = (0, import_react29.useCallback)(() => {
|
|
5281
5451
|
setReloadCount((count) => count + 1);
|
|
5282
5452
|
}, []);
|
|
5283
|
-
const loadMore = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
5424
|
-
const [loaded, setLoaded] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
5447
|
-
/* @__PURE__ */ (0,
|
|
5448
|
-
fieldErrors._ ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
5474
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
5475
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
5511
|
-
const [removeFailed, setRemoveFailed] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
5526
|
-
removeFailed ? /* @__PURE__ */ (0,
|
|
5527
|
-
/* @__PURE__ */ (0,
|
|
5528
|
-
searchable && !hideSearch ? /* @__PURE__ */ (0,
|
|
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,
|
|
5539
|
-
/* @__PURE__ */ (0,
|
|
5540
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5552
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
5739
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
|
|
5570
5740
|
] }) }),
|
|
5571
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5586
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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 && !
|
|
5623
|
-
|
|
5624
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
5625
|
-
editing ? /* @__PURE__ */ (0,
|
|
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
|
|
5650
|
-
var
|
|
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,
|
|
5668
|
-
const [over, setOver] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
5695
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
5724
|
-
/* @__PURE__ */ (0,
|
|
5725
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
5728
|
-
inColumn.map((record) => /* @__PURE__ */ (0,
|
|
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,
|
|
5741
|
-
shown.map((candidate) => /* @__PURE__ */ (0,
|
|
5742
|
-
/* @__PURE__ */ (0,
|
|
5743
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
5757
|
-
/* @__PURE__ */ (0,
|
|
5758
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
5809
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 ||
|
|
5851
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
5862
|
-
/* @__PURE__ */ (0,
|
|
5863
|
-
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0,
|
|
5864
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6042
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-chart-label", children: entry.label })
|
|
5873
6043
|
] }, entry.key)) }),
|
|
5874
|
-
/* @__PURE__ */ (0,
|
|
5875
|
-
/* @__PURE__ */ (0,
|
|
5876
|
-
/* @__PURE__ */ (0,
|
|
5877
|
-
/* @__PURE__ */ (0,
|
|
5878
|
-
/* @__PURE__ */ (0,
|
|
5879
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
5882
|
-
/* @__PURE__ */ (0,
|
|
5883
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
5943
|
-
var
|
|
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,
|
|
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,
|
|
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 ||
|
|
5965
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
5990
|
-
/* @__PURE__ */ (0,
|
|
5991
|
-
/* @__PURE__ */ (0,
|
|
5992
|
-
/* @__PURE__ */ (0,
|
|
5993
|
-
writable ? /* @__PURE__ */ (0,
|
|
5994
|
-
writable ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6011
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
6030
|
-
var
|
|
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,
|
|
6071
|
-
const [
|
|
6072
|
-
const [managedBy, setManagedBy] = (0,
|
|
6073
|
-
const [schedule, setSchedule] = (0,
|
|
6074
|
-
const [busy, setBusy] = (0,
|
|
6075
|
-
const [error, setError] = (0,
|
|
6076
|
-
const [step, setStep] = (0,
|
|
6077
|
-
const [reason, setReason] = (0,
|
|
6078
|
-
const [comment, setComment] = (0,
|
|
6079
|
-
const load = (0,
|
|
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,
|
|
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 ||
|
|
6115
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
6130
|
-
error ? /* @__PURE__ */ (0,
|
|
6131
|
-
/* @__PURE__ */ (0,
|
|
6132
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
6175
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6191
|
-
/* @__PURE__ */ (0,
|
|
6192
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6197
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
6255
|
-
/* @__PURE__ */ (0,
|
|
6256
|
-
REASONS.map((option) => /* @__PURE__ */ (0,
|
|
6257
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6437
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: option.label })
|
|
6268
6438
|
] }, option.value))
|
|
6269
6439
|
] }),
|
|
6270
|
-
/* @__PURE__ */ (0,
|
|
6271
|
-
/* @__PURE__ */ (0,
|
|
6272
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6284
|
-
/* @__PURE__ */ (0,
|
|
6285
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
6489
|
+
var import_react39 = require("react");
|
|
6320
6490
|
|
|
6321
6491
|
// src/CreditBalances.tsx
|
|
6322
|
-
var
|
|
6323
|
-
var
|
|
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,
|
|
6359
|
-
const [error, setError] = (0,
|
|
6360
|
-
const [saved, setSaved] = (0,
|
|
6361
|
-
const [pack, setPack] = (0,
|
|
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,
|
|
6416
|
-
/* @__PURE__ */ (0,
|
|
6417
|
-
/* @__PURE__ */ (0,
|
|
6418
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6430
|
-
error ? /* @__PURE__ */ (0,
|
|
6431
|
-
saved ? /* @__PURE__ */ (0,
|
|
6432
|
-
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0,
|
|
6433
|
-
/* @__PURE__ */ (0,
|
|
6434
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
6462
|
-
/* @__PURE__ */ (0,
|
|
6463
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6468
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6485
|
-
/* @__PURE__ */ (0,
|
|
6486
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6497
|
-
/* @__PURE__ */ (0,
|
|
6498
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6509
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
6532
|
-
const [version, setVersion] = (0,
|
|
6533
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
6557
|
-
credits.managedBy ? /* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
6581
|
-
var
|
|
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,
|
|
6589
|
-
const [busy, setBusy] = (0,
|
|
6590
|
-
const [error, setError] = (0,
|
|
6591
|
-
const [version, setVersion] = (0,
|
|
6592
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
6640
|
-
/* @__PURE__ */ (0,
|
|
6641
|
-
card ? /* @__PURE__ */ (0,
|
|
6642
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6654
|
-
others.length > 0 ? /* @__PURE__ */ (0,
|
|
6655
|
-
/* @__PURE__ */ (0,
|
|
6656
|
-
others.map((saved) => /* @__PURE__ */ (0,
|
|
6657
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6663
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6694
|
-
/* @__PURE__ */ (0,
|
|
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
|
|
6724
|
-
var
|
|
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,
|
|
6758
|
-
const [preview, setPreview] = (0,
|
|
6759
|
-
const [error, setError] = (0,
|
|
6760
|
-
const [needsCard, setNeedsCard] = (0,
|
|
6761
|
-
const [busy, setBusy] = (0,
|
|
6762
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
6818
|
-
/* @__PURE__ */ (0,
|
|
6819
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
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,
|
|
6833
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6842
|
-
changes.length === 0 ? /* @__PURE__ */ (0,
|
|
6843
|
-
/* @__PURE__ */ (0,
|
|
6844
|
-
/* @__PURE__ */ (0,
|
|
6845
|
-
/* @__PURE__ */ (0,
|
|
6846
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6849
|
-
/* @__PURE__ */ (0,
|
|
6850
|
-
/* @__PURE__ */ (0,
|
|
6851
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6865
|
-
Number(now.credit) > 0 ? /* @__PURE__ */ (0,
|
|
6866
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6876
|
-
/* @__PURE__ */ (0,
|
|
6877
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
6880
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
6890
|
-
/* @__PURE__ */ (0,
|
|
6891
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
6918
|
-
needsCard ? /* @__PURE__ */ (0,
|
|
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,
|
|
6921
|
-
] }) : /* @__PURE__ */ (0,
|
|
6922
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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,
|
|
6953
|
-
const [failed, setFailed] = (0,
|
|
6954
|
-
const [version, setVersion] = (0,
|
|
6955
|
-
const [reviewing, setReviewing] = (0,
|
|
6956
|
-
const [notice, setNotice] = (0,
|
|
6957
|
-
(0,
|
|
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,
|
|
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,
|
|
6981
|
-
if (sessionLoading) return shell(/* @__PURE__ */ (0,
|
|
6982
|
-
if (!token) return shell(/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
6993
|
-
notice ? /* @__PURE__ */ (0,
|
|
6994
|
-
/* @__PURE__ */ (0,
|
|
6995
|
-
canChange ? /* @__PURE__ */ (0,
|
|
6996
|
-
canChange && quantityPriced ? /* @__PURE__ */ (0,
|
|
6997
|
-
reviewing ? /* @__PURE__ */ (0,
|
|
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,
|
|
7011
|
-
/* @__PURE__ */ (0,
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7025
|
-
managedBy ? null : /* @__PURE__ */ (0,
|
|
7026
|
-
/* @__PURE__ */ (0,
|
|
7027
|
-
billingDetails === void 0 ? /* @__PURE__ */ (0,
|
|
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
|
|
7034
|
-
var
|
|
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,
|
|
7052
|
-
const [credentials, setCredentials] = (0,
|
|
7053
|
-
const [
|
|
7054
|
-
const [busy, setBusy] = (0,
|
|
7055
|
-
const [error, setError] = (0,
|
|
7056
|
-
const [creating, setCreating] = (0,
|
|
7057
|
-
const [name, setName] = (0,
|
|
7058
|
-
const [chosen, setChosen] = (0,
|
|
7059
|
-
const [resourceId, setResourceId] = (0,
|
|
7060
|
-
const [issued, setIssued] = (0,
|
|
7061
|
-
const load = (0,
|
|
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,
|
|
7252
|
+
(0, import_react40.useEffect)(() => {
|
|
7083
7253
|
void load();
|
|
7084
7254
|
}, [load]);
|
|
7085
|
-
if (sessionLoading ||
|
|
7086
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
7105
|
-
error ? /* @__PURE__ */ (0,
|
|
7106
|
-
resources.length > 1 ? /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
7116
|
-
resource.rateLimit ? /* @__PURE__ */ (0,
|
|
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,
|
|
7123
|
-
credentials.length === 0 ? /* @__PURE__ */ (0,
|
|
7124
|
-
/* @__PURE__ */ (0,
|
|
7125
|
-
/* @__PURE__ */ (0,
|
|
7126
|
-
/* @__PURE__ */ (0,
|
|
7127
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7301
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
|
|
7132
7302
|
] }),
|
|
7133
|
-
/* @__PURE__ */ (0,
|
|
7134
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
7188
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7191
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
7216
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7226
|
-
resource.availableScopes.map((scope) => /* @__PURE__ */ (0,
|
|
7227
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7238
|
-
scope.description ? /* @__PURE__ */ (0,
|
|
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,
|
|
7244
|
-
/* @__PURE__ */ (0,
|
|
7245
|
-
/* @__PURE__ */ (0,
|
|
7246
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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: "
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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,
|