@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.js
CHANGED
|
@@ -162,7 +162,7 @@ var STYLESHEET = `
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
/* The recommended plan. Lifted rather than merely tinted: on a pricing table
|
|
165
|
-
the eye needs one obvious default, and
|
|
165
|
+
the eye needs one obvious default, and color alone does not survive being
|
|
166
166
|
viewed in greyscale or by someone who cannot distinguish the accent. */
|
|
167
167
|
.b316-plan-featured {
|
|
168
168
|
border-color: var(--b316-color-primary);
|
|
@@ -549,7 +549,7 @@ var STYLESHEET_EXTRA = `
|
|
|
549
549
|
.b316-mfa-uri { font-size: 0.9em; }
|
|
550
550
|
.b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
|
|
551
551
|
.b316-mfa-code-list code { user-select: all; }
|
|
552
|
-
/* The
|
|
552
|
+
/* The enrollment choices: whole-width buttons with their explanation inside,
|
|
553
553
|
so the explanation is part of what a screen reader announces. */
|
|
554
554
|
.b316-mfa-methods { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }
|
|
555
555
|
.b316-mfa-method { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; }
|
|
@@ -680,7 +680,7 @@ function Base316Provider({
|
|
|
680
680
|
const [internalToken, setInternalToken] = useState(null);
|
|
681
681
|
const [session, setSession] = useState(null);
|
|
682
682
|
const [branding, setBranding] = useState(null);
|
|
683
|
-
const [
|
|
683
|
+
const [loading2, setLoading] = useState(true);
|
|
684
684
|
const token = controlled ? controlledToken : internalToken;
|
|
685
685
|
useEffect(() => {
|
|
686
686
|
if (controlled) {
|
|
@@ -742,8 +742,8 @@ function Base316Provider({
|
|
|
742
742
|
setSession(null);
|
|
743
743
|
}, [client, token, setToken]);
|
|
744
744
|
const value = useMemo(
|
|
745
|
-
() => ({ client, branding, token, setToken, session, loading, refresh, signOut }),
|
|
746
|
-
[client, branding, token, setToken, session,
|
|
745
|
+
() => ({ client, branding, token, setToken, session, loading: loading2, refresh, signOut }),
|
|
746
|
+
[client, branding, token, setToken, session, loading2, refresh, signOut]
|
|
747
747
|
);
|
|
748
748
|
return /* @__PURE__ */ jsx(Base316Context.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
749
749
|
"div",
|
|
@@ -752,7 +752,7 @@ function Base316Provider({
|
|
|
752
752
|
style: appearanceToStyle({
|
|
753
753
|
// Whatever was set in the sign-in designer arrives here, so a
|
|
754
754
|
// customer styles their login once on Base316 and the embedded
|
|
755
|
-
// components follow — rather than configuring the same
|
|
755
|
+
// components follow — rather than configuring the same colors
|
|
756
756
|
// twice and watching them drift apart.
|
|
757
757
|
//
|
|
758
758
|
// An explicit `appearance` still wins, because a host that has
|
|
@@ -775,8 +775,8 @@ function useBase316() {
|
|
|
775
775
|
return value;
|
|
776
776
|
}
|
|
777
777
|
function useSession() {
|
|
778
|
-
const { session, loading } = useBase316();
|
|
779
|
-
return { session, loading };
|
|
778
|
+
const { session, loading: loading2 } = useBase316();
|
|
779
|
+
return { session, loading: loading2 };
|
|
780
780
|
}
|
|
781
781
|
|
|
782
782
|
// src/Branding.tsx
|
|
@@ -2651,8 +2651,72 @@ import {
|
|
|
2651
2651
|
Base316Error as Base316Error3,
|
|
2652
2652
|
needsSecondFactor as needsSecondFactor2
|
|
2653
2653
|
} from "@base316/sdk";
|
|
2654
|
-
import { useEffect as
|
|
2655
|
-
|
|
2654
|
+
import { useEffect as useEffect10, useState as useState9 } from "react";
|
|
2655
|
+
|
|
2656
|
+
// src/CaptchaWidget.tsx
|
|
2657
|
+
import { useEffect as useEffect9, useRef as useRef3 } from "react";
|
|
2658
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
2659
|
+
var SCRIPT_URL = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
|
|
2660
|
+
var loading = null;
|
|
2661
|
+
function loadTurnstile() {
|
|
2662
|
+
if (window.turnstile) {
|
|
2663
|
+
return Promise.resolve(window.turnstile);
|
|
2664
|
+
}
|
|
2665
|
+
loading ??= new Promise((resolve, reject) => {
|
|
2666
|
+
const script = document.createElement("script");
|
|
2667
|
+
script.src = SCRIPT_URL;
|
|
2668
|
+
script.async = true;
|
|
2669
|
+
script.onload = () => {
|
|
2670
|
+
if (window.turnstile) {
|
|
2671
|
+
resolve(window.turnstile);
|
|
2672
|
+
} else {
|
|
2673
|
+
reject(new Error("Turnstile did not start"));
|
|
2674
|
+
}
|
|
2675
|
+
};
|
|
2676
|
+
script.onerror = () => {
|
|
2677
|
+
loading = null;
|
|
2678
|
+
reject(new Error("Turnstile could not be loaded"));
|
|
2679
|
+
};
|
|
2680
|
+
document.head.appendChild(script);
|
|
2681
|
+
});
|
|
2682
|
+
return loading;
|
|
2683
|
+
}
|
|
2684
|
+
function CaptchaWidget({
|
|
2685
|
+
siteKey,
|
|
2686
|
+
onToken
|
|
2687
|
+
}) {
|
|
2688
|
+
const container = useRef3(null);
|
|
2689
|
+
const latest = useRef3(onToken);
|
|
2690
|
+
useEffect9(() => {
|
|
2691
|
+
latest.current = onToken;
|
|
2692
|
+
}, [onToken]);
|
|
2693
|
+
useEffect9(() => {
|
|
2694
|
+
let widgetId = null;
|
|
2695
|
+
let cancelled = false;
|
|
2696
|
+
loadTurnstile().then((turnstile) => {
|
|
2697
|
+
if (cancelled || !container.current) {
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
widgetId = turnstile.render(container.current, {
|
|
2701
|
+
sitekey: siteKey,
|
|
2702
|
+
size: "flexible",
|
|
2703
|
+
callback: (token) => latest.current(token),
|
|
2704
|
+
"expired-callback": () => latest.current(null),
|
|
2705
|
+
"error-callback": () => latest.current(null)
|
|
2706
|
+
});
|
|
2707
|
+
}).catch((cause) => console.error("[base316] CAPTCHA unavailable", cause));
|
|
2708
|
+
return () => {
|
|
2709
|
+
cancelled = true;
|
|
2710
|
+
if (widgetId) {
|
|
2711
|
+
window.turnstile?.remove(widgetId);
|
|
2712
|
+
}
|
|
2713
|
+
};
|
|
2714
|
+
}, [siteKey]);
|
|
2715
|
+
return /* @__PURE__ */ jsx11("div", { ref: container, className: "b316-captcha" });
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
// src/SignUp.tsx
|
|
2719
|
+
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2656
2720
|
var DEFAULT_SIGN_UP_LABELS = {
|
|
2657
2721
|
name: "Name",
|
|
2658
2722
|
email: "Email",
|
|
@@ -2672,7 +2736,8 @@ var DEFAULT_SIGN_UP_LABELS = {
|
|
|
2672
2736
|
joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
|
|
2673
2737
|
continueWith: (name) => `Continue with ${name}`,
|
|
2674
2738
|
or: "or",
|
|
2675
|
-
closed: "This application is not accepting new accounts right now."
|
|
2739
|
+
closed: "This application is not accepting new accounts right now.",
|
|
2740
|
+
noMethods: "Creating an account is not available here right now."
|
|
2676
2741
|
};
|
|
2677
2742
|
function describeRules(policy, labels) {
|
|
2678
2743
|
const extras = [
|
|
@@ -2711,15 +2776,17 @@ function SignUp({
|
|
|
2711
2776
|
const [confirmEmail, setConfirmEmail] = useState9(false);
|
|
2712
2777
|
const [urlInvitation, setUrlInvitation] = useState9(null);
|
|
2713
2778
|
const [loaded, setLoaded] = useState9(null);
|
|
2779
|
+
const [captchaToken, setCaptchaToken] = useState9(null);
|
|
2780
|
+
const [captchaRound, setCaptchaRound] = useState9(0);
|
|
2714
2781
|
const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
|
|
2715
2782
|
const preview = loaded && loaded.token === invitation ? loaded.preview : null;
|
|
2716
|
-
|
|
2783
|
+
useEffect10(() => {
|
|
2717
2784
|
if (suppliedInvitation !== void 0 || typeof window === "undefined") {
|
|
2718
2785
|
return;
|
|
2719
2786
|
}
|
|
2720
2787
|
setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
|
|
2721
2788
|
}, [suppliedInvitation]);
|
|
2722
|
-
|
|
2789
|
+
useEffect10(() => {
|
|
2723
2790
|
if (!invitation) {
|
|
2724
2791
|
return;
|
|
2725
2792
|
}
|
|
@@ -2734,7 +2801,7 @@ function SignUp({
|
|
|
2734
2801
|
cancelled = true;
|
|
2735
2802
|
};
|
|
2736
2803
|
}, [client, invitation]);
|
|
2737
|
-
|
|
2804
|
+
useEffect10(() => {
|
|
2738
2805
|
let cancelled = false;
|
|
2739
2806
|
client.auth.passwordPolicy().then((loaded2) => {
|
|
2740
2807
|
if (!cancelled) {
|
|
@@ -2754,7 +2821,8 @@ function SignUp({
|
|
|
2754
2821
|
email,
|
|
2755
2822
|
password,
|
|
2756
2823
|
name: name || void 0,
|
|
2757
|
-
invitationToken: invitation ?? void 0
|
|
2824
|
+
invitationToken: invitation ?? void 0,
|
|
2825
|
+
captchaToken: captchaToken ?? void 0
|
|
2758
2826
|
});
|
|
2759
2827
|
if (created.invitationAccepted && created.organizationId) {
|
|
2760
2828
|
onJoined?.(created.organizationId);
|
|
@@ -2764,6 +2832,8 @@ function SignUp({
|
|
|
2764
2832
|
setError(
|
|
2765
2833
|
cause instanceof Base316Error3 && (cause.code === "INVALID_REQUEST" || cause.code === "RATE_LIMITED" || cause.code === "CONFLICT") && cause.message ? cause.message : labels.genericError
|
|
2766
2834
|
);
|
|
2835
|
+
setCaptchaToken(null);
|
|
2836
|
+
setCaptchaRound((round) => round + 1);
|
|
2767
2837
|
setBusy(false);
|
|
2768
2838
|
return;
|
|
2769
2839
|
}
|
|
@@ -2792,21 +2862,24 @@ function SignUp({
|
|
|
2792
2862
|
}
|
|
2793
2863
|
}
|
|
2794
2864
|
if (pending) {
|
|
2795
|
-
return /* @__PURE__ */
|
|
2865
|
+
return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx12(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
|
|
2796
2866
|
}
|
|
2797
2867
|
if (confirmEmail) {
|
|
2798
2868
|
return /* @__PURE__ */ jsxs10("div", { className: cls("b316-card", className), style, children: [
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
/* @__PURE__ */
|
|
2869
|
+
/* @__PURE__ */ jsx12("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
|
|
2870
|
+
/* @__PURE__ */ jsx12("output", { className: "b316-muted", children: labels.confirmEmail(email) })
|
|
2801
2871
|
] });
|
|
2802
2872
|
}
|
|
2803
2873
|
if (!offered.signUp && !invitation) {
|
|
2804
|
-
return /* @__PURE__ */
|
|
2874
|
+
return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx12("output", { className: "b316-muted", children: labels.closed }) });
|
|
2805
2875
|
}
|
|
2806
2876
|
const socialOptions = invitation ? [] : offered.social;
|
|
2877
|
+
if (!offered.password && socialOptions.length === 0) {
|
|
2878
|
+
return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx12("output", { className: "b316-muted", children: labels.noMethods }) });
|
|
2879
|
+
}
|
|
2807
2880
|
return /* @__PURE__ */ jsxs10("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
|
|
2808
2881
|
socialOptions.length > 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2809
|
-
/* @__PURE__ */
|
|
2882
|
+
/* @__PURE__ */ jsx12(
|
|
2810
2883
|
SocialButtons,
|
|
2811
2884
|
{
|
|
2812
2885
|
options: socialOptions,
|
|
@@ -2829,14 +2902,14 @@ function SignUp({
|
|
|
2829
2902
|
}
|
|
2830
2903
|
}
|
|
2831
2904
|
),
|
|
2832
|
-
offered.password ? /* @__PURE__ */
|
|
2905
|
+
offered.password ? /* @__PURE__ */ jsx12("div", { className: "b316-divider", children: labels.or }) : null
|
|
2833
2906
|
] }) : null,
|
|
2834
|
-
preview ? /* @__PURE__ */
|
|
2835
|
-
error ? /* @__PURE__ */
|
|
2907
|
+
preview ? /* @__PURE__ */ jsx12("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
|
|
2908
|
+
error ? /* @__PURE__ */ jsx12("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
2836
2909
|
offered.password || socialOptions.length === 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
2837
2910
|
/* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
|
|
2838
|
-
/* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
2911
|
+
/* @__PURE__ */ jsx12("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
|
|
2912
|
+
/* @__PURE__ */ jsx12(
|
|
2840
2913
|
"input",
|
|
2841
2914
|
{
|
|
2842
2915
|
id: "b316-name",
|
|
@@ -2848,8 +2921,8 @@ function SignUp({
|
|
|
2848
2921
|
)
|
|
2849
2922
|
] }),
|
|
2850
2923
|
/* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
|
|
2851
|
-
/* @__PURE__ */
|
|
2852
|
-
/* @__PURE__ */
|
|
2924
|
+
/* @__PURE__ */ jsx12("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
|
|
2925
|
+
/* @__PURE__ */ jsx12(
|
|
2853
2926
|
"input",
|
|
2854
2927
|
{
|
|
2855
2928
|
id: "b316-signup-email",
|
|
@@ -2863,8 +2936,8 @@ function SignUp({
|
|
|
2863
2936
|
)
|
|
2864
2937
|
] }),
|
|
2865
2938
|
/* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
|
|
2866
|
-
/* @__PURE__ */
|
|
2867
|
-
/* @__PURE__ */
|
|
2939
|
+
/* @__PURE__ */ jsx12("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
|
|
2940
|
+
/* @__PURE__ */ jsx12(
|
|
2868
2941
|
"input",
|
|
2869
2942
|
{
|
|
2870
2943
|
id: "b316-signup-password",
|
|
@@ -2879,31 +2952,39 @@ function SignUp({
|
|
|
2879
2952
|
required: true
|
|
2880
2953
|
}
|
|
2881
2954
|
),
|
|
2882
|
-
policy ? /* @__PURE__ */
|
|
2955
|
+
policy ? /* @__PURE__ */ jsx12("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
|
|
2883
2956
|
] }),
|
|
2884
|
-
/* @__PURE__ */
|
|
2957
|
+
methodsState.methods?.captcha && !invitation ? /* @__PURE__ */ jsx12(
|
|
2958
|
+
CaptchaWidget,
|
|
2959
|
+
{
|
|
2960
|
+
siteKey: methodsState.methods.captcha.siteKey,
|
|
2961
|
+
onToken: setCaptchaToken
|
|
2962
|
+
},
|
|
2963
|
+
captchaRound
|
|
2964
|
+
) : null,
|
|
2965
|
+
/* @__PURE__ */ jsx12("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
|
|
2885
2966
|
] }) : null
|
|
2886
2967
|
] });
|
|
2887
2968
|
}
|
|
2888
2969
|
|
|
2889
2970
|
// src/UserProfile.tsx
|
|
2890
|
-
import { jsx as
|
|
2971
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2891
2972
|
function UserProfile({ className, style }) {
|
|
2892
|
-
const { session, loading, signOut } = useBase316();
|
|
2893
|
-
if (
|
|
2894
|
-
return /* @__PURE__ */
|
|
2973
|
+
const { session, loading: loading2, signOut } = useBase316();
|
|
2974
|
+
if (loading2) {
|
|
2975
|
+
return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
2895
2976
|
}
|
|
2896
2977
|
if (!session) {
|
|
2897
|
-
return /* @__PURE__ */
|
|
2978
|
+
return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: "Not signed in." });
|
|
2898
2979
|
}
|
|
2899
2980
|
const user = session.user ?? {};
|
|
2900
|
-
return /* @__PURE__ */
|
|
2981
|
+
return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs11("div", { className: "b316-row", children: [
|
|
2901
2982
|
/* @__PURE__ */ jsxs11("div", { children: [
|
|
2902
|
-
/* @__PURE__ */
|
|
2903
|
-
user.name && user.email ? /* @__PURE__ */
|
|
2904
|
-
user.emailVerified === false ? /* @__PURE__ */
|
|
2983
|
+
/* @__PURE__ */ jsx13("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
|
|
2984
|
+
user.name && user.email ? /* @__PURE__ */ jsx13("div", { className: "b316-muted", children: user.email }) : null,
|
|
2985
|
+
user.emailVerified === false ? /* @__PURE__ */ jsx13("div", { className: "b316-muted", children: "Email not verified" }) : null
|
|
2905
2986
|
] }),
|
|
2906
|
-
/* @__PURE__ */
|
|
2987
|
+
/* @__PURE__ */ jsx13(
|
|
2907
2988
|
"button",
|
|
2908
2989
|
{
|
|
2909
2990
|
type: "button",
|
|
@@ -2917,11 +2998,11 @@ function UserProfile({ className, style }) {
|
|
|
2917
2998
|
|
|
2918
2999
|
// src/PasskeyManager.tsx
|
|
2919
3000
|
import { isPasskeySupported as isPasskeySupported2 } from "@base316/sdk";
|
|
2920
|
-
import { useCallback as useCallback5, useEffect as
|
|
3001
|
+
import { useCallback as useCallback5, useEffect as useEffect12, useState as useState11 } from "react";
|
|
2921
3002
|
|
|
2922
3003
|
// src/confirm.tsx
|
|
2923
|
-
import { useEffect as
|
|
2924
|
-
import { jsx as
|
|
3004
|
+
import { useEffect as useEffect11, useRef as useRef4, useState as useState10 } from "react";
|
|
3005
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2925
3006
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
2926
3007
|
function ConfirmButton({
|
|
2927
3008
|
children,
|
|
@@ -2932,8 +3013,8 @@ function ConfirmButton({
|
|
|
2932
3013
|
timeoutMs = DEFAULT_TIMEOUT_MS
|
|
2933
3014
|
}) {
|
|
2934
3015
|
const [armed, setArmed] = useState10(false);
|
|
2935
|
-
const confirmRef =
|
|
2936
|
-
|
|
3016
|
+
const confirmRef = useRef4(null);
|
|
3017
|
+
useEffect11(() => {
|
|
2937
3018
|
if (!armed) {
|
|
2938
3019
|
return;
|
|
2939
3020
|
}
|
|
@@ -2942,7 +3023,7 @@ function ConfirmButton({
|
|
|
2942
3023
|
return () => clearTimeout(timer);
|
|
2943
3024
|
}, [armed, timeoutMs]);
|
|
2944
3025
|
if (!armed) {
|
|
2945
|
-
return /* @__PURE__ */
|
|
3026
|
+
return /* @__PURE__ */ jsx14(
|
|
2946
3027
|
"button",
|
|
2947
3028
|
{
|
|
2948
3029
|
type: "button",
|
|
@@ -2957,7 +3038,7 @@ function ConfirmButton({
|
|
|
2957
3038
|
// No `role="group"`: both buttons already say what they do, and the
|
|
2958
3039
|
// grouping would only repeat the question a screen reader has just read.
|
|
2959
3040
|
/* @__PURE__ */ jsxs12("span", { className: "b316-confirm", children: [
|
|
2960
|
-
/* @__PURE__ */
|
|
3041
|
+
/* @__PURE__ */ jsx14(
|
|
2961
3042
|
"button",
|
|
2962
3043
|
{
|
|
2963
3044
|
ref: confirmRef,
|
|
@@ -2971,7 +3052,7 @@ function ConfirmButton({
|
|
|
2971
3052
|
children: confirmLabel
|
|
2972
3053
|
}
|
|
2973
3054
|
),
|
|
2974
|
-
/* @__PURE__ */
|
|
3055
|
+
/* @__PURE__ */ jsx14(
|
|
2975
3056
|
"button",
|
|
2976
3057
|
{
|
|
2977
3058
|
type: "button",
|
|
@@ -2985,7 +3066,7 @@ function ConfirmButton({
|
|
|
2985
3066
|
}
|
|
2986
3067
|
|
|
2987
3068
|
// src/PasskeyManager.tsx
|
|
2988
|
-
import { jsx as
|
|
3069
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2989
3070
|
function PasskeyManager({
|
|
2990
3071
|
className,
|
|
2991
3072
|
style,
|
|
@@ -3010,7 +3091,7 @@ function PasskeyManager({
|
|
|
3010
3091
|
setPasskeys(null);
|
|
3011
3092
|
}
|
|
3012
3093
|
}, [client, token]);
|
|
3013
|
-
|
|
3094
|
+
useEffect12(() => {
|
|
3014
3095
|
if (!isPasskeySupported2()) {
|
|
3015
3096
|
return;
|
|
3016
3097
|
}
|
|
@@ -3047,17 +3128,17 @@ function PasskeyManager({
|
|
|
3047
3128
|
}
|
|
3048
3129
|
};
|
|
3049
3130
|
return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card", className), style, children: [
|
|
3050
|
-
/* @__PURE__ */
|
|
3051
|
-
/* @__PURE__ */
|
|
3052
|
-
passkeys === null ? /* @__PURE__ */
|
|
3131
|
+
/* @__PURE__ */ jsx15("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
|
|
3132
|
+
/* @__PURE__ */ jsx15("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." }),
|
|
3133
|
+
passkeys === null ? /* @__PURE__ */ jsx15("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ jsx15("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ jsx15("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ jsxs13("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
|
|
3053
3134
|
/* @__PURE__ */ jsxs13("div", { children: [
|
|
3054
|
-
/* @__PURE__ */
|
|
3135
|
+
/* @__PURE__ */ jsx15("div", { children: passkey.name || "Passkey" }),
|
|
3055
3136
|
/* @__PURE__ */ jsxs13("div", { className: "b316-muted", children: [
|
|
3056
3137
|
passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
|
|
3057
3138
|
passkey.backedUp ? "" : " \xB7 this device only"
|
|
3058
3139
|
] })
|
|
3059
3140
|
] }),
|
|
3060
|
-
/* @__PURE__ */
|
|
3141
|
+
/* @__PURE__ */ jsx15(
|
|
3061
3142
|
ConfirmButton,
|
|
3062
3143
|
{
|
|
3063
3144
|
className: "b316-button b316-button-secondary",
|
|
@@ -3067,9 +3148,9 @@ function PasskeyManager({
|
|
|
3067
3148
|
}
|
|
3068
3149
|
)
|
|
3069
3150
|
] }, passkey.id)) }),
|
|
3070
|
-
error ? /* @__PURE__ */
|
|
3151
|
+
error ? /* @__PURE__ */ jsx15("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
|
|
3071
3152
|
/* @__PURE__ */ jsxs13("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
|
|
3072
|
-
/* @__PURE__ */
|
|
3153
|
+
/* @__PURE__ */ jsx15(
|
|
3073
3154
|
"input",
|
|
3074
3155
|
{
|
|
3075
3156
|
className: "b316-input",
|
|
@@ -3078,7 +3159,7 @@ function PasskeyManager({
|
|
|
3078
3159
|
onChange: (event) => setName(event.target.value)
|
|
3079
3160
|
}
|
|
3080
3161
|
),
|
|
3081
|
-
/* @__PURE__ */
|
|
3162
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
|
|
3082
3163
|
] })
|
|
3083
3164
|
] });
|
|
3084
3165
|
}
|
|
@@ -3088,8 +3169,8 @@ function formatDate(value) {
|
|
|
3088
3169
|
}
|
|
3089
3170
|
|
|
3090
3171
|
// src/ActiveSessions.tsx
|
|
3091
|
-
import { useCallback as useCallback6, useEffect as
|
|
3092
|
-
import { jsx as
|
|
3172
|
+
import { useCallback as useCallback6, useEffect as useEffect13, useState as useState12 } from "react";
|
|
3173
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3093
3174
|
function describeDevice(userAgent) {
|
|
3094
3175
|
if (!userAgent) {
|
|
3095
3176
|
return null;
|
|
@@ -3121,15 +3202,15 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
3121
3202
|
setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
|
|
3122
3203
|
});
|
|
3123
3204
|
}, [client, token]);
|
|
3124
|
-
|
|
3205
|
+
useEffect13(load, [load]);
|
|
3125
3206
|
if (!token) {
|
|
3126
3207
|
return null;
|
|
3127
3208
|
}
|
|
3128
3209
|
if (error) {
|
|
3129
|
-
return /* @__PURE__ */
|
|
3210
|
+
return /* @__PURE__ */ jsx16("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx16("div", { className: "b316-error", role: "alert", children: error }) });
|
|
3130
3211
|
}
|
|
3131
3212
|
if (!sessions) {
|
|
3132
|
-
return /* @__PURE__ */
|
|
3213
|
+
return /* @__PURE__ */ jsx16("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
3133
3214
|
}
|
|
3134
3215
|
async function revokeOthers() {
|
|
3135
3216
|
setBusy(true);
|
|
@@ -3145,15 +3226,15 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
3145
3226
|
}
|
|
3146
3227
|
return /* @__PURE__ */ jsxs14("div", { className: cls("b316-card b316-sessions", className), style, children: [
|
|
3147
3228
|
/* @__PURE__ */ jsxs14("div", { className: "b316-sessions-head", children: [
|
|
3148
|
-
/* @__PURE__ */
|
|
3149
|
-
sessions.length > 1 ? /* @__PURE__ */
|
|
3229
|
+
/* @__PURE__ */ jsx16("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
|
|
3230
|
+
sessions.length > 1 ? /* @__PURE__ */ jsx16("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
|
|
3150
3231
|
] }),
|
|
3151
|
-
/* @__PURE__ */
|
|
3232
|
+
/* @__PURE__ */ jsx16("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ jsxs14("li", { className: "b316-session", children: [
|
|
3152
3233
|
/* @__PURE__ */ jsxs14("div", { className: "b316-session-device", children: [
|
|
3153
3234
|
describeDevice(session.userAgent) ?? "Unknown device",
|
|
3154
3235
|
session.impersonatedBy ? (
|
|
3155
3236
|
// Worth saying loudly: somebody is acting as this account.
|
|
3156
|
-
/* @__PURE__ */
|
|
3237
|
+
/* @__PURE__ */ jsx16("span", { className: "b316-chip", children: " Support access" })
|
|
3157
3238
|
) : null
|
|
3158
3239
|
] }),
|
|
3159
3240
|
/* @__PURE__ */ jsxs14("div", { className: "b316-muted", children: [
|
|
@@ -3162,13 +3243,13 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
3162
3243
|
when(session.lastSeenAt)
|
|
3163
3244
|
] })
|
|
3164
3245
|
] }, session.id)) }),
|
|
3165
|
-
sessions.length === 0 ? /* @__PURE__ */
|
|
3246
|
+
sessions.length === 0 ? /* @__PURE__ */ jsx16("div", { className: "b316-muted", children: "No active sessions." }) : null
|
|
3166
3247
|
] });
|
|
3167
3248
|
}
|
|
3168
3249
|
|
|
3169
3250
|
// src/DeviceApproval.tsx
|
|
3170
3251
|
import { useState as useState13 } from "react";
|
|
3171
|
-
import { jsx as
|
|
3252
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3172
3253
|
function DeviceApproval({
|
|
3173
3254
|
userCode = "",
|
|
3174
3255
|
onDecided,
|
|
@@ -3214,8 +3295,8 @@ function DeviceApproval({
|
|
|
3214
3295
|
}
|
|
3215
3296
|
if (decided !== null) {
|
|
3216
3297
|
return /* @__PURE__ */ jsxs15("div", { className: cls("b316-card b316-device", className), style, children: [
|
|
3217
|
-
/* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3298
|
+
/* @__PURE__ */ jsx17("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
|
|
3299
|
+
/* @__PURE__ */ jsx17("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." })
|
|
3219
3300
|
] });
|
|
3220
3301
|
}
|
|
3221
3302
|
if (request) {
|
|
@@ -3228,10 +3309,10 @@ function DeviceApproval({
|
|
|
3228
3309
|
request.clientName,
|
|
3229
3310
|
" is asking to sign in as you."
|
|
3230
3311
|
] }),
|
|
3231
|
-
request.scopes.length > 0 ? /* @__PURE__ */
|
|
3232
|
-
error ? /* @__PURE__ */
|
|
3312
|
+
request.scopes.length > 0 ? /* @__PURE__ */ jsx17("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ jsx17("li", { children: scope }, scope)) }) : null,
|
|
3313
|
+
error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3233
3314
|
/* @__PURE__ */ jsxs15("div", { className: "b316-device-actions", children: [
|
|
3234
|
-
/* @__PURE__ */
|
|
3315
|
+
/* @__PURE__ */ jsx17(
|
|
3235
3316
|
"button",
|
|
3236
3317
|
{
|
|
3237
3318
|
type: "button",
|
|
@@ -3241,7 +3322,7 @@ function DeviceApproval({
|
|
|
3241
3322
|
children: busy ? "Approving\u2026" : "Approve"
|
|
3242
3323
|
}
|
|
3243
3324
|
),
|
|
3244
|
-
/* @__PURE__ */
|
|
3325
|
+
/* @__PURE__ */ jsx17(
|
|
3245
3326
|
"button",
|
|
3246
3327
|
{
|
|
3247
3328
|
type: "button",
|
|
@@ -3255,10 +3336,10 @@ function DeviceApproval({
|
|
|
3255
3336
|
] });
|
|
3256
3337
|
}
|
|
3257
3338
|
return /* @__PURE__ */ jsxs15("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
|
|
3258
|
-
/* @__PURE__ */
|
|
3259
|
-
/* @__PURE__ */
|
|
3260
|
-
error ? /* @__PURE__ */
|
|
3261
|
-
/* @__PURE__ */
|
|
3339
|
+
/* @__PURE__ */ jsx17("h3", { className: "b316-device-title", children: "Connect your device" }),
|
|
3340
|
+
/* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
|
|
3341
|
+
error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3342
|
+
/* @__PURE__ */ jsx17(
|
|
3262
3343
|
"input",
|
|
3263
3344
|
{
|
|
3264
3345
|
className: "b316-input",
|
|
@@ -3271,13 +3352,13 @@ function DeviceApproval({
|
|
|
3271
3352
|
"aria-label": "Device code"
|
|
3272
3353
|
}
|
|
3273
3354
|
),
|
|
3274
|
-
/* @__PURE__ */
|
|
3355
|
+
/* @__PURE__ */ jsx17("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
|
|
3275
3356
|
] });
|
|
3276
3357
|
}
|
|
3277
3358
|
|
|
3278
3359
|
// src/PrivacyControls.tsx
|
|
3279
3360
|
import { useState as useState14 } from "react";
|
|
3280
|
-
import { jsx as
|
|
3361
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3281
3362
|
function PrivacyControls({
|
|
3282
3363
|
confirmWord = "DELETE",
|
|
3283
3364
|
onErased,
|
|
@@ -3324,21 +3405,21 @@ function PrivacyControls({
|
|
|
3324
3405
|
}
|
|
3325
3406
|
}
|
|
3326
3407
|
return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-privacy", className), style, children: [
|
|
3327
|
-
/* @__PURE__ */
|
|
3328
|
-
error ? /* @__PURE__ */
|
|
3408
|
+
/* @__PURE__ */ jsx18("h3", { className: "b316-privacy-title", children: "Your data" }),
|
|
3409
|
+
error ? /* @__PURE__ */ jsx18("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3329
3410
|
/* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
|
|
3330
3411
|
/* @__PURE__ */ jsxs16("div", { children: [
|
|
3331
|
-
/* @__PURE__ */
|
|
3332
|
-
/* @__PURE__ */
|
|
3412
|
+
/* @__PURE__ */ jsx18("p", { children: "Download a copy" }),
|
|
3413
|
+
/* @__PURE__ */ jsx18("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." })
|
|
3333
3414
|
] }),
|
|
3334
|
-
/* @__PURE__ */
|
|
3415
|
+
/* @__PURE__ */ jsx18("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
|
|
3335
3416
|
] }),
|
|
3336
3417
|
/* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
|
|
3337
3418
|
/* @__PURE__ */ jsxs16("div", { children: [
|
|
3338
|
-
/* @__PURE__ */
|
|
3339
|
-
/* @__PURE__ */
|
|
3419
|
+
/* @__PURE__ */ jsx18("p", { children: "Delete your account" }),
|
|
3420
|
+
/* @__PURE__ */ jsx18("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
|
|
3340
3421
|
] }),
|
|
3341
|
-
confirming ? null : /* @__PURE__ */
|
|
3422
|
+
confirming ? null : /* @__PURE__ */ jsx18(
|
|
3342
3423
|
"button",
|
|
3343
3424
|
{
|
|
3344
3425
|
type: "button",
|
|
@@ -3355,7 +3436,7 @@ function PrivacyControls({
|
|
|
3355
3436
|
confirmWord,
|
|
3356
3437
|
" to confirm"
|
|
3357
3438
|
] }),
|
|
3358
|
-
/* @__PURE__ */
|
|
3439
|
+
/* @__PURE__ */ jsx18(
|
|
3359
3440
|
"input",
|
|
3360
3441
|
{
|
|
3361
3442
|
id: "b316-privacy-confirm",
|
|
@@ -3366,7 +3447,7 @@ function PrivacyControls({
|
|
|
3366
3447
|
}
|
|
3367
3448
|
),
|
|
3368
3449
|
/* @__PURE__ */ jsxs16("div", { className: "b316-privacy-actions", children: [
|
|
3369
|
-
/* @__PURE__ */
|
|
3450
|
+
/* @__PURE__ */ jsx18(
|
|
3370
3451
|
"button",
|
|
3371
3452
|
{
|
|
3372
3453
|
type: "button",
|
|
@@ -3378,7 +3459,7 @@ function PrivacyControls({
|
|
|
3378
3459
|
children: "Cancel"
|
|
3379
3460
|
}
|
|
3380
3461
|
),
|
|
3381
|
-
/* @__PURE__ */
|
|
3462
|
+
/* @__PURE__ */ jsx18(
|
|
3382
3463
|
"button",
|
|
3383
3464
|
{
|
|
3384
3465
|
type: "button",
|
|
@@ -3399,7 +3480,7 @@ import { useState as useState15 } from "react";
|
|
|
3399
3480
|
// src/QrCode.tsx
|
|
3400
3481
|
import qrcode from "qrcode-generator";
|
|
3401
3482
|
import { useMemo as useMemo2 } from "react";
|
|
3402
|
-
import { jsx as
|
|
3483
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3403
3484
|
var QUIET_ZONE = 4;
|
|
3404
3485
|
function utf8Binary(value) {
|
|
3405
3486
|
let binary = "";
|
|
@@ -3438,15 +3519,15 @@ function QrCode({ value, label, size = 180, className }) {
|
|
|
3438
3519
|
shapeRendering: "crispEdges",
|
|
3439
3520
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3440
3521
|
children: [
|
|
3441
|
-
/* @__PURE__ */
|
|
3442
|
-
/* @__PURE__ */
|
|
3522
|
+
/* @__PURE__ */ jsx19("rect", { width: extent, height: extent, fill: "#ffffff" }),
|
|
3523
|
+
/* @__PURE__ */ jsx19("path", { d: path, fill: "#000000" })
|
|
3443
3524
|
]
|
|
3444
3525
|
}
|
|
3445
3526
|
);
|
|
3446
3527
|
}
|
|
3447
3528
|
|
|
3448
3529
|
// src/TwoFactorManager.tsx
|
|
3449
|
-
import { jsx as
|
|
3530
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3450
3531
|
function groupKey(secret) {
|
|
3451
3532
|
return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
|
|
3452
3533
|
}
|
|
@@ -3543,16 +3624,16 @@ function TwoFactorManager({
|
|
|
3543
3624
|
}
|
|
3544
3625
|
}
|
|
3545
3626
|
return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card b316-mfa", className), style, children: [
|
|
3546
|
-
/* @__PURE__ */
|
|
3547
|
-
error ? /* @__PURE__ */
|
|
3627
|
+
/* @__PURE__ */ jsx20("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
|
|
3628
|
+
error ? /* @__PURE__ */ jsx20("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3548
3629
|
stage.name === "saved" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-codes", children: [
|
|
3549
|
-
/* @__PURE__ */
|
|
3550
|
-
/* @__PURE__ */
|
|
3551
|
-
/* @__PURE__ */
|
|
3630
|
+
/* @__PURE__ */ jsx20("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." }),
|
|
3631
|
+
/* @__PURE__ */ jsx20("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx20("li", { children: /* @__PURE__ */ jsx20("code", { children: recovery }) }, recovery)) }),
|
|
3632
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
|
|
3552
3633
|
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
|
|
3553
|
-
/* @__PURE__ */
|
|
3554
|
-
/* @__PURE__ */
|
|
3555
|
-
/* @__PURE__ */
|
|
3634
|
+
/* @__PURE__ */ jsx20("p", { children: "We will text a code to this number now, and each time you sign in." }),
|
|
3635
|
+
/* @__PURE__ */ jsx20("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
|
|
3636
|
+
/* @__PURE__ */ jsx20(
|
|
3556
3637
|
"input",
|
|
3557
3638
|
{
|
|
3558
3639
|
id: "b316-mfa-phone",
|
|
@@ -3565,7 +3646,7 @@ function TwoFactorManager({
|
|
|
3565
3646
|
}
|
|
3566
3647
|
),
|
|
3567
3648
|
/* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
|
|
3568
|
-
/* @__PURE__ */
|
|
3649
|
+
/* @__PURE__ */ jsx20(
|
|
3569
3650
|
"button",
|
|
3570
3651
|
{
|
|
3571
3652
|
type: "button",
|
|
@@ -3574,7 +3655,7 @@ function TwoFactorManager({
|
|
|
3574
3655
|
children: "Cancel"
|
|
3575
3656
|
}
|
|
3576
3657
|
),
|
|
3577
|
-
/* @__PURE__ */
|
|
3658
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
|
|
3578
3659
|
] })
|
|
3579
3660
|
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
|
|
3580
3661
|
/* @__PURE__ */ jsxs18("p", { children: [
|
|
@@ -3582,8 +3663,8 @@ function TwoFactorManager({
|
|
|
3582
3663
|
stage.destinationHint,
|
|
3583
3664
|
". Enter it below to turn this on."
|
|
3584
3665
|
] }),
|
|
3585
|
-
/* @__PURE__ */
|
|
3586
|
-
/* @__PURE__ */
|
|
3666
|
+
/* @__PURE__ */ jsx20("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3667
|
+
/* @__PURE__ */ jsx20(
|
|
3587
3668
|
"input",
|
|
3588
3669
|
{
|
|
3589
3670
|
id: "b316-mfa-code",
|
|
@@ -3595,7 +3676,7 @@ function TwoFactorManager({
|
|
|
3595
3676
|
}
|
|
3596
3677
|
),
|
|
3597
3678
|
/* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
|
|
3598
|
-
/* @__PURE__ */
|
|
3679
|
+
/* @__PURE__ */ jsx20(
|
|
3599
3680
|
"button",
|
|
3600
3681
|
{
|
|
3601
3682
|
type: "button",
|
|
@@ -3604,7 +3685,7 @@ function TwoFactorManager({
|
|
|
3604
3685
|
children: "Cancel"
|
|
3605
3686
|
}
|
|
3606
3687
|
),
|
|
3607
|
-
/* @__PURE__ */
|
|
3688
|
+
/* @__PURE__ */ jsx20(
|
|
3608
3689
|
"button",
|
|
3609
3690
|
{
|
|
3610
3691
|
type: "button",
|
|
@@ -3616,8 +3697,8 @@ function TwoFactorManager({
|
|
|
3616
3697
|
)
|
|
3617
3698
|
] })
|
|
3618
3699
|
] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
|
|
3619
|
-
/* @__PURE__ */
|
|
3620
|
-
/* @__PURE__ */
|
|
3700
|
+
/* @__PURE__ */ jsx20("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
|
|
3701
|
+
/* @__PURE__ */ jsx20(
|
|
3621
3702
|
QrCode,
|
|
3622
3703
|
{
|
|
3623
3704
|
className: "b316-mfa-qr",
|
|
@@ -3626,12 +3707,12 @@ function TwoFactorManager({
|
|
|
3626
3707
|
}
|
|
3627
3708
|
),
|
|
3628
3709
|
/* @__PURE__ */ jsxs18("div", { className: "b316-mfa-secret", children: [
|
|
3629
|
-
/* @__PURE__ */
|
|
3630
|
-
/* @__PURE__ */
|
|
3710
|
+
/* @__PURE__ */ jsx20("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
|
|
3711
|
+
/* @__PURE__ */ jsx20("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
|
|
3631
3712
|
] }),
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3634
|
-
/* @__PURE__ */
|
|
3713
|
+
/* @__PURE__ */ jsx20("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
|
|
3714
|
+
/* @__PURE__ */ jsx20("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3715
|
+
/* @__PURE__ */ jsx20(
|
|
3635
3716
|
"input",
|
|
3636
3717
|
{
|
|
3637
3718
|
id: "b316-mfa-code",
|
|
@@ -3643,7 +3724,7 @@ function TwoFactorManager({
|
|
|
3643
3724
|
}
|
|
3644
3725
|
),
|
|
3645
3726
|
/* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
|
|
3646
|
-
/* @__PURE__ */
|
|
3727
|
+
/* @__PURE__ */ jsx20(
|
|
3647
3728
|
"button",
|
|
3648
3729
|
{
|
|
3649
3730
|
type: "button",
|
|
@@ -3652,7 +3733,7 @@ function TwoFactorManager({
|
|
|
3652
3733
|
children: "Cancel"
|
|
3653
3734
|
}
|
|
3654
3735
|
),
|
|
3655
|
-
/* @__PURE__ */
|
|
3736
|
+
/* @__PURE__ */ jsx20(
|
|
3656
3737
|
"button",
|
|
3657
3738
|
{
|
|
3658
3739
|
type: "button",
|
|
@@ -3664,8 +3745,8 @@ function TwoFactorManager({
|
|
|
3664
3745
|
)
|
|
3665
3746
|
] })
|
|
3666
3747
|
] }) : on ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-on", children: [
|
|
3667
|
-
/* @__PURE__ */
|
|
3668
|
-
/* @__PURE__ */
|
|
3748
|
+
/* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
|
|
3749
|
+
/* @__PURE__ */ jsx20(
|
|
3669
3750
|
ConfirmButton,
|
|
3670
3751
|
{
|
|
3671
3752
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3676,10 +3757,10 @@ function TwoFactorManager({
|
|
|
3676
3757
|
}
|
|
3677
3758
|
)
|
|
3678
3759
|
] }) : /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-off", children: [
|
|
3679
|
-
/* @__PURE__ */
|
|
3760
|
+
/* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
|
|
3680
3761
|
/* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
|
|
3681
|
-
/* @__PURE__ */
|
|
3682
|
-
/* @__PURE__ */
|
|
3762
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
|
|
3763
|
+
/* @__PURE__ */ jsx20(
|
|
3683
3764
|
"button",
|
|
3684
3765
|
{
|
|
3685
3766
|
type: "button",
|
|
@@ -3689,7 +3770,7 @@ function TwoFactorManager({
|
|
|
3689
3770
|
children: "Email me a code"
|
|
3690
3771
|
}
|
|
3691
3772
|
),
|
|
3692
|
-
allowSms ? /* @__PURE__ */
|
|
3773
|
+
allowSms ? /* @__PURE__ */ jsx20(
|
|
3693
3774
|
"button",
|
|
3694
3775
|
{
|
|
3695
3776
|
type: "button",
|
|
@@ -3706,7 +3787,7 @@ function TwoFactorManager({
|
|
|
3706
3787
|
|
|
3707
3788
|
// src/ForgotPassword.tsx
|
|
3708
3789
|
import { useState as useState16 } from "react";
|
|
3709
|
-
import { jsx as
|
|
3790
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3710
3791
|
function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
3711
3792
|
const { client } = useBase316();
|
|
3712
3793
|
const [email, setEmail] = useState16("");
|
|
@@ -3729,21 +3810,21 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3729
3810
|
}
|
|
3730
3811
|
if (sent) {
|
|
3731
3812
|
return /* @__PURE__ */ jsxs19("div", { className: cls("b316-card", className), style, children: [
|
|
3732
|
-
/* @__PURE__ */
|
|
3813
|
+
/* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Check your email" }),
|
|
3733
3814
|
/* @__PURE__ */ jsxs19("p", { className: "b316-muted", children: [
|
|
3734
3815
|
"If there is an account for ",
|
|
3735
3816
|
email.trim(),
|
|
3736
3817
|
", a link to set a new password is on its way."
|
|
3737
3818
|
] }),
|
|
3738
|
-
signInUrl ? /* @__PURE__ */
|
|
3819
|
+
signInUrl ? /* @__PURE__ */ jsx21("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3739
3820
|
] });
|
|
3740
3821
|
}
|
|
3741
3822
|
return /* @__PURE__ */ jsxs19("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3742
|
-
/* @__PURE__ */
|
|
3743
|
-
error ? /* @__PURE__ */
|
|
3823
|
+
/* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Reset your password" }),
|
|
3824
|
+
error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3744
3825
|
/* @__PURE__ */ jsxs19("div", { className: "b316-field", children: [
|
|
3745
|
-
/* @__PURE__ */
|
|
3746
|
-
/* @__PURE__ */
|
|
3826
|
+
/* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
|
|
3827
|
+
/* @__PURE__ */ jsx21(
|
|
3747
3828
|
"input",
|
|
3748
3829
|
{
|
|
3749
3830
|
id: "b316-forgot-email",
|
|
@@ -3756,14 +3837,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3756
3837
|
}
|
|
3757
3838
|
)
|
|
3758
3839
|
] }),
|
|
3759
|
-
/* @__PURE__ */
|
|
3760
|
-
signInUrl ? /* @__PURE__ */
|
|
3840
|
+
/* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
|
|
3841
|
+
signInUrl ? /* @__PURE__ */ jsx21("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3761
3842
|
] });
|
|
3762
3843
|
}
|
|
3763
3844
|
|
|
3764
3845
|
// src/ResetPassword.tsx
|
|
3765
|
-
import { useEffect as
|
|
3766
|
-
import { jsx as
|
|
3846
|
+
import { useEffect as useEffect14, useState as useState17 } from "react";
|
|
3847
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3767
3848
|
function ResetPassword({
|
|
3768
3849
|
token: supplied,
|
|
3769
3850
|
onReset,
|
|
@@ -3778,7 +3859,7 @@ function ResetPassword({
|
|
|
3778
3859
|
const [done, setDone] = useState17(false);
|
|
3779
3860
|
const [busy, setBusy] = useState17(false);
|
|
3780
3861
|
const [error, setError] = useState17(null);
|
|
3781
|
-
|
|
3862
|
+
useEffect14(() => {
|
|
3782
3863
|
if (supplied || typeof window === "undefined") {
|
|
3783
3864
|
return;
|
|
3784
3865
|
}
|
|
@@ -3814,23 +3895,23 @@ function ResetPassword({
|
|
|
3814
3895
|
}
|
|
3815
3896
|
if (done) {
|
|
3816
3897
|
return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
|
|
3817
|
-
/* @__PURE__ */
|
|
3818
|
-
/* @__PURE__ */
|
|
3819
|
-
signInUrl ? /* @__PURE__ */
|
|
3898
|
+
/* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Password changed" }),
|
|
3899
|
+
/* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "You can sign in with your new password." }),
|
|
3900
|
+
signInUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
|
|
3820
3901
|
] });
|
|
3821
3902
|
}
|
|
3822
3903
|
if (!token) {
|
|
3823
3904
|
return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
|
|
3824
|
-
/* @__PURE__ */
|
|
3825
|
-
/* @__PURE__ */
|
|
3905
|
+
/* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Nothing to reset" }),
|
|
3906
|
+
/* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
|
|
3826
3907
|
] });
|
|
3827
3908
|
}
|
|
3828
3909
|
return /* @__PURE__ */ jsxs20("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3829
|
-
/* @__PURE__ */
|
|
3830
|
-
error ? /* @__PURE__ */
|
|
3910
|
+
/* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Choose a new password" }),
|
|
3911
|
+
error ? /* @__PURE__ */ jsx22("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3831
3912
|
/* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
|
|
3832
|
-
/* @__PURE__ */
|
|
3833
|
-
/* @__PURE__ */
|
|
3913
|
+
/* @__PURE__ */ jsx22("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
|
|
3914
|
+
/* @__PURE__ */ jsx22(
|
|
3834
3915
|
"input",
|
|
3835
3916
|
{
|
|
3836
3917
|
id: "b316-reset-password",
|
|
@@ -3844,8 +3925,8 @@ function ResetPassword({
|
|
|
3844
3925
|
)
|
|
3845
3926
|
] }),
|
|
3846
3927
|
/* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
|
|
3847
|
-
/* @__PURE__ */
|
|
3848
|
-
/* @__PURE__ */
|
|
3928
|
+
/* @__PURE__ */ jsx22("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
|
|
3929
|
+
/* @__PURE__ */ jsx22(
|
|
3849
3930
|
"input",
|
|
3850
3931
|
{
|
|
3851
3932
|
id: "b316-reset-confirm",
|
|
@@ -3858,13 +3939,13 @@ function ResetPassword({
|
|
|
3858
3939
|
}
|
|
3859
3940
|
)
|
|
3860
3941
|
] }),
|
|
3861
|
-
/* @__PURE__ */
|
|
3942
|
+
/* @__PURE__ */ jsx22("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
|
|
3862
3943
|
] });
|
|
3863
3944
|
}
|
|
3864
3945
|
|
|
3865
3946
|
// src/VerifyEmail.tsx
|
|
3866
|
-
import { useEffect as
|
|
3867
|
-
import { Fragment as Fragment7, jsx as
|
|
3947
|
+
import { useEffect as useEffect15, useRef as useRef5, useState as useState18 } from "react";
|
|
3948
|
+
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3868
3949
|
function VerifyEmail({
|
|
3869
3950
|
token: supplied,
|
|
3870
3951
|
onVerified,
|
|
@@ -3874,8 +3955,8 @@ function VerifyEmail({
|
|
|
3874
3955
|
}) {
|
|
3875
3956
|
const { client } = useBase316();
|
|
3876
3957
|
const [state, setState] = useState18("waiting");
|
|
3877
|
-
const spent =
|
|
3878
|
-
|
|
3958
|
+
const spent = useRef5(false);
|
|
3959
|
+
useEffect15(() => {
|
|
3879
3960
|
if (spent.current) {
|
|
3880
3961
|
return;
|
|
3881
3962
|
}
|
|
@@ -3901,22 +3982,22 @@ function VerifyEmail({
|
|
|
3901
3982
|
setState("failed");
|
|
3902
3983
|
});
|
|
3903
3984
|
}, [client, supplied, onVerified]);
|
|
3904
|
-
return /* @__PURE__ */
|
|
3905
|
-
/* @__PURE__ */
|
|
3906
|
-
/* @__PURE__ */
|
|
3907
|
-
continueUrl ? /* @__PURE__ */
|
|
3985
|
+
return /* @__PURE__ */ jsx23("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
3986
|
+
/* @__PURE__ */ jsx23("h3", { className: "b316-form-title", children: "Email confirmed" }),
|
|
3987
|
+
/* @__PURE__ */ jsx23("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
|
|
3988
|
+
continueUrl ? /* @__PURE__ */ jsx23("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
|
|
3908
3989
|
] }) : state === "failed" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
3909
|
-
/* @__PURE__ */
|
|
3910
|
-
/* @__PURE__ */
|
|
3990
|
+
/* @__PURE__ */ jsx23("h3", { className: "b316-form-title", children: "That link did not work" }),
|
|
3991
|
+
/* @__PURE__ */ jsx23("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
|
|
3911
3992
|
] }) : state === "missing" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
3912
|
-
/* @__PURE__ */
|
|
3913
|
-
/* @__PURE__ */
|
|
3914
|
-
] }) : /* @__PURE__ */
|
|
3993
|
+
/* @__PURE__ */ jsx23("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
|
|
3994
|
+
/* @__PURE__ */ jsx23("p", { className: "b316-muted", children: "This page needs the link from your email." })
|
|
3995
|
+
] }) : /* @__PURE__ */ jsx23("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
|
|
3915
3996
|
}
|
|
3916
3997
|
|
|
3917
3998
|
// src/TeamMembers.tsx
|
|
3918
|
-
import { useCallback as useCallback7, useEffect as
|
|
3919
|
-
import { Fragment as Fragment8, jsx as
|
|
3999
|
+
import { useCallback as useCallback7, useEffect as useEffect16, useState as useState19 } from "react";
|
|
4000
|
+
import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3920
4001
|
function TeamMembers({
|
|
3921
4002
|
organizationId,
|
|
3922
4003
|
onInvited,
|
|
@@ -3943,8 +4024,8 @@ function TeamMembers({
|
|
|
3943
4024
|
(cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
|
|
3944
4025
|
);
|
|
3945
4026
|
}, [client, token]);
|
|
3946
|
-
|
|
3947
|
-
|
|
4027
|
+
useEffect16(load, [load]);
|
|
4028
|
+
useEffect16(() => {
|
|
3948
4029
|
if (!token || !chosen) {
|
|
3949
4030
|
return;
|
|
3950
4031
|
}
|
|
@@ -3975,10 +4056,10 @@ function TeamMembers({
|
|
|
3975
4056
|
return null;
|
|
3976
4057
|
}
|
|
3977
4058
|
if (!teams) {
|
|
3978
|
-
return /* @__PURE__ */
|
|
4059
|
+
return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
|
|
3979
4060
|
}
|
|
3980
4061
|
if (!chosen) {
|
|
3981
|
-
return /* @__PURE__ */
|
|
4062
|
+
return /* @__PURE__ */ jsx24("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." });
|
|
3982
4063
|
}
|
|
3983
4064
|
const canManage = invitations !== null;
|
|
3984
4065
|
async function invite(event) {
|
|
@@ -4029,7 +4110,7 @@ function TeamMembers({
|
|
|
4029
4110
|
}
|
|
4030
4111
|
}
|
|
4031
4112
|
return /* @__PURE__ */ jsxs22("div", { className: cls("b316-card b316-team", className), style, children: [
|
|
4032
|
-
/* @__PURE__ */
|
|
4113
|
+
/* @__PURE__ */ jsx24("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
|
|
4033
4114
|
team?.inherited ? (
|
|
4034
4115
|
// Not a member of this team, so not in the list below and with nothing
|
|
4035
4116
|
// to leave: access comes from the team that manages it, and ends there.
|
|
@@ -4040,18 +4121,18 @@ function TeamMembers({
|
|
|
4040
4121
|
"."
|
|
4041
4122
|
] })
|
|
4042
4123
|
) : null,
|
|
4043
|
-
error ? /* @__PURE__ */
|
|
4044
|
-
/* @__PURE__ */
|
|
4124
|
+
error ? /* @__PURE__ */ jsx24("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
4125
|
+
/* @__PURE__ */ jsx24("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
|
|
4045
4126
|
/* @__PURE__ */ jsxs22("div", { children: [
|
|
4046
|
-
/* @__PURE__ */
|
|
4127
|
+
/* @__PURE__ */ jsx24("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
|
|
4047
4128
|
/* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
|
|
4048
4129
|
member.user.email,
|
|
4049
4130
|
member.user.id === session?.userId ? " \xB7 you" : ""
|
|
4050
4131
|
] })
|
|
4051
4132
|
] }),
|
|
4052
4133
|
/* @__PURE__ */ jsxs22("div", { className: "b316-team-member-side", children: [
|
|
4053
|
-
/* @__PURE__ */
|
|
4054
|
-
canManage || member.user.id === session?.userId ? /* @__PURE__ */
|
|
4134
|
+
/* @__PURE__ */ jsx24("span", { className: "b316-chip", children: member.role.name }),
|
|
4135
|
+
canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx24(
|
|
4055
4136
|
ConfirmButton,
|
|
4056
4137
|
{
|
|
4057
4138
|
className: "b316-button-quiet b316-danger",
|
|
@@ -4064,10 +4145,10 @@ function TeamMembers({
|
|
|
4064
4145
|
] })
|
|
4065
4146
|
] }, member.id)) }),
|
|
4066
4147
|
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs22(Fragment8, { children: [
|
|
4067
|
-
/* @__PURE__ */
|
|
4068
|
-
/* @__PURE__ */
|
|
4148
|
+
/* @__PURE__ */ jsx24("h4", { className: "b316-team-subtitle", children: "Invited" }),
|
|
4149
|
+
/* @__PURE__ */ jsx24("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
|
|
4069
4150
|
/* @__PURE__ */ jsxs22("div", { children: [
|
|
4070
|
-
/* @__PURE__ */
|
|
4151
|
+
/* @__PURE__ */ jsx24("div", { children: invitation.email }),
|
|
4071
4152
|
/* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
|
|
4072
4153
|
invitation.role.name,
|
|
4073
4154
|
" \xB7 expires",
|
|
@@ -4075,7 +4156,7 @@ function TeamMembers({
|
|
|
4075
4156
|
new Date(invitation.expiresAt).toLocaleDateString()
|
|
4076
4157
|
] })
|
|
4077
4158
|
] }),
|
|
4078
|
-
/* @__PURE__ */
|
|
4159
|
+
/* @__PURE__ */ jsx24(
|
|
4079
4160
|
"button",
|
|
4080
4161
|
{
|
|
4081
4162
|
type: "button",
|
|
@@ -4087,9 +4168,9 @@ function TeamMembers({
|
|
|
4087
4168
|
] }, invitation.id)) })
|
|
4088
4169
|
] }) : null,
|
|
4089
4170
|
canManage ? /* @__PURE__ */ jsxs22("form", { className: "b316-team-invite", onSubmit: invite, children: [
|
|
4090
|
-
/* @__PURE__ */
|
|
4171
|
+
/* @__PURE__ */ jsx24("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
|
|
4091
4172
|
/* @__PURE__ */ jsxs22("div", { className: "b316-team-invite-row", children: [
|
|
4092
|
-
/* @__PURE__ */
|
|
4173
|
+
/* @__PURE__ */ jsx24(
|
|
4093
4174
|
"input",
|
|
4094
4175
|
{
|
|
4095
4176
|
id: "b316-invite-email",
|
|
@@ -4101,19 +4182,19 @@ function TeamMembers({
|
|
|
4101
4182
|
onChange: (event) => setEmail(event.target.value)
|
|
4102
4183
|
}
|
|
4103
4184
|
),
|
|
4104
|
-
/* @__PURE__ */
|
|
4185
|
+
/* @__PURE__ */ jsx24("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
|
|
4105
4186
|
] })
|
|
4106
4187
|
] }) : null,
|
|
4107
4188
|
copied ? /* @__PURE__ */ jsxs22("div", { className: "b316-team-link", children: [
|
|
4108
|
-
/* @__PURE__ */
|
|
4109
|
-
/* @__PURE__ */
|
|
4189
|
+
/* @__PURE__ */ jsx24("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
|
|
4190
|
+
/* @__PURE__ */ jsx24("code", { children: copied })
|
|
4110
4191
|
] }) : null
|
|
4111
4192
|
] });
|
|
4112
4193
|
}
|
|
4113
4194
|
|
|
4114
4195
|
// src/AcceptInvitation.tsx
|
|
4115
|
-
import { useEffect as
|
|
4116
|
-
import { Fragment as Fragment9, jsx as
|
|
4196
|
+
import { useEffect as useEffect17, useState as useState20 } from "react";
|
|
4197
|
+
import { Fragment as Fragment9, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4117
4198
|
function signUpUrlWithInvitation(url, token) {
|
|
4118
4199
|
const [beforeHash, ...hash] = url.split("#");
|
|
4119
4200
|
const base = beforeHash ?? "";
|
|
@@ -4137,13 +4218,13 @@ function AcceptInvitation({
|
|
|
4137
4218
|
const [state, setState] = useState20("loading");
|
|
4138
4219
|
const [error, setError] = useState20(null);
|
|
4139
4220
|
const [busy, setBusy] = useState20(false);
|
|
4140
|
-
|
|
4221
|
+
useEffect17(() => {
|
|
4141
4222
|
if (supplied || typeof window === "undefined") {
|
|
4142
4223
|
return;
|
|
4143
4224
|
}
|
|
4144
4225
|
setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
|
|
4145
4226
|
}, [supplied]);
|
|
4146
|
-
|
|
4227
|
+
useEffect17(() => {
|
|
4147
4228
|
if (!invitationToken) {
|
|
4148
4229
|
setState(supplied === void 0 ? "loading" : "invalid");
|
|
4149
4230
|
return;
|
|
@@ -4180,16 +4261,16 @@ function AcceptInvitation({
|
|
|
4180
4261
|
}
|
|
4181
4262
|
}
|
|
4182
4263
|
if (state === "loading") {
|
|
4183
|
-
return /* @__PURE__ */
|
|
4264
|
+
return /* @__PURE__ */ jsx25("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
4184
4265
|
}
|
|
4185
4266
|
if (state === "invalid") {
|
|
4186
4267
|
return /* @__PURE__ */ jsxs23("div", { className: cls("b316-card", className), style, children: [
|
|
4187
|
-
/* @__PURE__ */
|
|
4188
|
-
/* @__PURE__ */
|
|
4268
|
+
/* @__PURE__ */ jsx25("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
|
|
4269
|
+
/* @__PURE__ */ jsx25("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
|
|
4189
4270
|
] });
|
|
4190
4271
|
}
|
|
4191
4272
|
if (state === "accepted") {
|
|
4192
|
-
return /* @__PURE__ */
|
|
4273
|
+
return /* @__PURE__ */ jsx25("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs23("h3", { className: "b316-form-title", children: [
|
|
4193
4274
|
"You have joined ",
|
|
4194
4275
|
preview?.organizationName
|
|
4195
4276
|
] }) });
|
|
@@ -4206,7 +4287,7 @@ function AcceptInvitation({
|
|
|
4206
4287
|
" \xB7 ",
|
|
4207
4288
|
preview?.roleName
|
|
4208
4289
|
] }),
|
|
4209
|
-
error ? /* @__PURE__ */
|
|
4290
|
+
error ? /* @__PURE__ */ jsx25("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
4210
4291
|
!session ? /* @__PURE__ */ jsxs23(Fragment9, { children: [
|
|
4211
4292
|
/* @__PURE__ */ jsxs23("p", { children: [
|
|
4212
4293
|
"Sign in as ",
|
|
@@ -4214,8 +4295,8 @@ function AcceptInvitation({
|
|
|
4214
4295
|
" to accept."
|
|
4215
4296
|
] }),
|
|
4216
4297
|
/* @__PURE__ */ jsxs23("div", { className: "b316-invitation-actions", children: [
|
|
4217
|
-
signInUrl ? /* @__PURE__ */
|
|
4218
|
-
signUpUrl ? /* @__PURE__ */
|
|
4298
|
+
signInUrl ? /* @__PURE__ */ jsx25("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
|
|
4299
|
+
signUpUrl ? /* @__PURE__ */ jsx25(
|
|
4219
4300
|
"a",
|
|
4220
4301
|
{
|
|
4221
4302
|
className: "b316-button-link",
|
|
@@ -4235,13 +4316,13 @@ function AcceptInvitation({
|
|
|
4235
4316
|
preview?.email,
|
|
4236
4317
|
" \u2014 sign in as that address to accept it."
|
|
4237
4318
|
] })
|
|
4238
|
-
) : /* @__PURE__ */
|
|
4319
|
+
) : /* @__PURE__ */ jsx25("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
|
|
4239
4320
|
] });
|
|
4240
4321
|
}
|
|
4241
4322
|
|
|
4242
4323
|
// src/PayInvoice.tsx
|
|
4243
|
-
import { useEffect as
|
|
4244
|
-
import { jsx as
|
|
4324
|
+
import { useEffect as useEffect18, useRef as useRef6, useState as useState21 } from "react";
|
|
4325
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4245
4326
|
var STRIPE_SRC = "https://js.stripe.com/v3/";
|
|
4246
4327
|
function loadStripeScript() {
|
|
4247
4328
|
if (typeof window === "undefined") {
|
|
@@ -4273,14 +4354,14 @@ function PayInvoice({
|
|
|
4273
4354
|
style
|
|
4274
4355
|
}) {
|
|
4275
4356
|
const { client } = useBase316();
|
|
4276
|
-
const mountRef =
|
|
4277
|
-
const stripeRef =
|
|
4278
|
-
const elementsRef =
|
|
4357
|
+
const mountRef = useRef6(null);
|
|
4358
|
+
const stripeRef = useRef6(null);
|
|
4359
|
+
const elementsRef = useRef6(null);
|
|
4279
4360
|
const [ready, setReady] = useState21(false);
|
|
4280
4361
|
const [paying, setPaying] = useState21(false);
|
|
4281
4362
|
const [done, setDone] = useState21(false);
|
|
4282
4363
|
const [error, setError] = useState21(null);
|
|
4283
|
-
|
|
4364
|
+
useEffect18(() => {
|
|
4284
4365
|
let cancelled = false;
|
|
4285
4366
|
async function start() {
|
|
4286
4367
|
const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
|
|
@@ -4333,17 +4414,17 @@ function PayInvoice({
|
|
|
4333
4414
|
onPaid?.();
|
|
4334
4415
|
};
|
|
4335
4416
|
if (done) {
|
|
4336
|
-
return /* @__PURE__ */
|
|
4417
|
+
return /* @__PURE__ */ jsx26("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx26("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
|
|
4337
4418
|
}
|
|
4338
4419
|
return /* @__PURE__ */ jsxs24("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
|
|
4339
|
-
error ? /* @__PURE__ */
|
|
4340
|
-
/* @__PURE__ */
|
|
4341
|
-
/* @__PURE__ */
|
|
4420
|
+
error ? /* @__PURE__ */ jsx26("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
|
|
4421
|
+
/* @__PURE__ */ jsx26("div", { ref: mountRef, className: "b316-pay__element" }),
|
|
4422
|
+
/* @__PURE__ */ jsx26("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
|
|
4342
4423
|
] });
|
|
4343
4424
|
}
|
|
4344
4425
|
|
|
4345
4426
|
// src/usePaymentLink.ts
|
|
4346
|
-
import { useEffect as
|
|
4427
|
+
import { useEffect as useEffect19, useRef as useRef7, useState as useState22 } from "react";
|
|
4347
4428
|
function usePaymentLink({
|
|
4348
4429
|
token,
|
|
4349
4430
|
environmentId,
|
|
@@ -4352,9 +4433,9 @@ function usePaymentLink({
|
|
|
4352
4433
|
}) {
|
|
4353
4434
|
const { client } = useBase316();
|
|
4354
4435
|
const [status2, setStatus] = useState22({ state: "loading" });
|
|
4355
|
-
const onPaidRef =
|
|
4436
|
+
const onPaidRef = useRef7(onPaid);
|
|
4356
4437
|
onPaidRef.current = onPaid;
|
|
4357
|
-
|
|
4438
|
+
useEffect19(() => {
|
|
4358
4439
|
let stopped = false;
|
|
4359
4440
|
let timer;
|
|
4360
4441
|
const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
|
|
@@ -4406,7 +4487,7 @@ function usePaymentLink({
|
|
|
4406
4487
|
import { useState as useState24 } from "react";
|
|
4407
4488
|
|
|
4408
4489
|
// src/usePlans.ts
|
|
4409
|
-
import { useCallback as useCallback8, useEffect as
|
|
4490
|
+
import { useCallback as useCallback8, useEffect as useEffect20, useState as useState23 } from "react";
|
|
4410
4491
|
var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
|
|
4411
4492
|
function usePlans(options = {}) {
|
|
4412
4493
|
const { client, token } = useBase316();
|
|
@@ -4419,7 +4500,7 @@ function usePlans(options = {}) {
|
|
|
4419
4500
|
const [reloadCount, setReloadCount] = useState23(0);
|
|
4420
4501
|
const supplied = options.currentPlanVersionId;
|
|
4421
4502
|
const discover = supplied === void 0;
|
|
4422
|
-
|
|
4503
|
+
useEffect20(() => {
|
|
4423
4504
|
let cancelled = false;
|
|
4424
4505
|
client.billing.plans().then((result) => {
|
|
4425
4506
|
if (!cancelled) {
|
|
@@ -4435,7 +4516,7 @@ function usePlans(options = {}) {
|
|
|
4435
4516
|
cancelled = true;
|
|
4436
4517
|
};
|
|
4437
4518
|
}, [client, reloadCount]);
|
|
4438
|
-
|
|
4519
|
+
useEffect20(() => {
|
|
4439
4520
|
if (!token) {
|
|
4440
4521
|
return;
|
|
4441
4522
|
}
|
|
@@ -4524,7 +4605,7 @@ function usePlans(options = {}) {
|
|
|
4524
4605
|
}
|
|
4525
4606
|
|
|
4526
4607
|
// src/PricingTable.tsx
|
|
4527
|
-
import { jsx as
|
|
4608
|
+
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
4528
4609
|
function formatAmount(amount, currency) {
|
|
4529
4610
|
if (amount === null) return "Free";
|
|
4530
4611
|
const value = Number(amount);
|
|
@@ -4590,13 +4671,13 @@ function PricingTable({
|
|
|
4590
4671
|
}
|
|
4591
4672
|
}
|
|
4592
4673
|
if (error) {
|
|
4593
|
-
return /* @__PURE__ */
|
|
4674
|
+
return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
|
|
4594
4675
|
}
|
|
4595
4676
|
if (!plans) {
|
|
4596
|
-
return /* @__PURE__ */
|
|
4677
|
+
return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
|
|
4597
4678
|
}
|
|
4598
4679
|
if (plans.length === 0) {
|
|
4599
|
-
return /* @__PURE__ */
|
|
4680
|
+
return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
|
|
4600
4681
|
}
|
|
4601
4682
|
const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
|
|
4602
4683
|
const anyDescription = plans.some((plan) => Boolean(plan.description));
|
|
@@ -4611,7 +4692,7 @@ function PricingTable({
|
|
|
4611
4692
|
managedBy.name ?? "the organization that manages your account",
|
|
4612
4693
|
". Ask them to change it."
|
|
4613
4694
|
] })
|
|
4614
|
-
) : lastError ? /* @__PURE__ */
|
|
4695
|
+
) : lastError ? /* @__PURE__ */ jsx27("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx27("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
|
|
4615
4696
|
plans.map((plan) => {
|
|
4616
4697
|
const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
|
|
4617
4698
|
const isCurrent = current === plan.planVersionId;
|
|
@@ -4622,18 +4703,18 @@ function PricingTable({
|
|
|
4622
4703
|
className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
|
|
4623
4704
|
children: [
|
|
4624
4705
|
/* @__PURE__ */ jsxs25("div", { className: "b316-plan-head", children: [
|
|
4625
|
-
anyFeatured ? /* @__PURE__ */
|
|
4626
|
-
/* @__PURE__ */
|
|
4627
|
-
anyDescription ? /* @__PURE__ */
|
|
4706
|
+
anyFeatured ? /* @__PURE__ */ jsx27("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
|
|
4707
|
+
/* @__PURE__ */ jsx27("div", { className: "b316-plan-name", children: plan.name }),
|
|
4708
|
+
anyDescription ? /* @__PURE__ */ jsx27("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
|
|
4628
4709
|
] }),
|
|
4629
4710
|
/* @__PURE__ */ jsxs25("div", { className: "b316-plan-pricing", children: [
|
|
4630
|
-
/* @__PURE__ */
|
|
4631
|
-
/* @__PURE__ */
|
|
4632
|
-
anyTrial ? /* @__PURE__ */
|
|
4711
|
+
/* @__PURE__ */ jsx27("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
|
|
4712
|
+
/* @__PURE__ */ jsx27("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
|
|
4713
|
+
anyTrial ? /* @__PURE__ */ jsx27("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
|
|
4633
4714
|
] }),
|
|
4634
|
-
/* @__PURE__ */
|
|
4635
|
-
/* @__PURE__ */
|
|
4636
|
-
/* @__PURE__ */
|
|
4715
|
+
/* @__PURE__ */ jsx27("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs25("li", { className: "b316-plan-feature", children: [
|
|
4716
|
+
/* @__PURE__ */ jsx27("span", { children: entitlement.featureName }),
|
|
4717
|
+
/* @__PURE__ */ jsx27("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
|
|
4637
4718
|
// A usage price on the feature makes the limit an
|
|
4638
4719
|
// allowance billed past, not a ceiling — the same
|
|
4639
4720
|
// rule `check()` applies (any non-FLAT price).
|
|
@@ -4642,7 +4723,7 @@ function PricingTable({
|
|
|
4642
4723
|
) ? `${entitlement.limit} included` : entitlement.limit
|
|
4643
4724
|
) })
|
|
4644
4725
|
] }, entitlement.featureId)) }),
|
|
4645
|
-
/* @__PURE__ */
|
|
4726
|
+
/* @__PURE__ */ jsx27("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx27(
|
|
4646
4727
|
"button",
|
|
4647
4728
|
{
|
|
4648
4729
|
type: "button",
|
|
@@ -4662,16 +4743,104 @@ function PricingTable({
|
|
|
4662
4743
|
] });
|
|
4663
4744
|
}
|
|
4664
4745
|
|
|
4746
|
+
// src/useAddons.ts
|
|
4747
|
+
import { useCallback as useCallback9, useEffect as useEffect21, useState as useState25 } from "react";
|
|
4748
|
+
function codeOf(cause) {
|
|
4749
|
+
const reason = cause?.reason;
|
|
4750
|
+
return typeof reason === "string" ? reason : "request_failed";
|
|
4751
|
+
}
|
|
4752
|
+
function useAddons() {
|
|
4753
|
+
const { client, token } = useBase316();
|
|
4754
|
+
const [attached, setAttached] = useState25(null);
|
|
4755
|
+
const [available, setAvailable] = useState25(null);
|
|
4756
|
+
const [loading2, setLoading] = useState25(true);
|
|
4757
|
+
const [lastError, setLastError] = useState25(null);
|
|
4758
|
+
const [busy, setBusy] = useState25(null);
|
|
4759
|
+
const [reloadCount, setReloadCount] = useState25(0);
|
|
4760
|
+
useEffect21(() => {
|
|
4761
|
+
let cancelled = false;
|
|
4762
|
+
if (!token) {
|
|
4763
|
+
return;
|
|
4764
|
+
}
|
|
4765
|
+
client.billing.addonsForSubscription(token).then((result) => {
|
|
4766
|
+
if (!cancelled) {
|
|
4767
|
+
setAttached(result.attached);
|
|
4768
|
+
setAvailable(result.available);
|
|
4769
|
+
setLastError(null);
|
|
4770
|
+
}
|
|
4771
|
+
}).catch((cause) => {
|
|
4772
|
+
if (!cancelled) {
|
|
4773
|
+
setAttached(null);
|
|
4774
|
+
setAvailable(null);
|
|
4775
|
+
setLastError(codeOf(cause));
|
|
4776
|
+
}
|
|
4777
|
+
}).finally(() => {
|
|
4778
|
+
if (!cancelled) {
|
|
4779
|
+
setLoading(false);
|
|
4780
|
+
}
|
|
4781
|
+
});
|
|
4782
|
+
return () => {
|
|
4783
|
+
cancelled = true;
|
|
4784
|
+
};
|
|
4785
|
+
}, [client, token, reloadCount]);
|
|
4786
|
+
const reload = useCallback9(() => {
|
|
4787
|
+
setLoading(true);
|
|
4788
|
+
setReloadCount((count) => count + 1);
|
|
4789
|
+
}, []);
|
|
4790
|
+
const run = useCallback9(
|
|
4791
|
+
async (key, action) => {
|
|
4792
|
+
if (!token) {
|
|
4793
|
+
setLastError("needs_sign_in");
|
|
4794
|
+
return null;
|
|
4795
|
+
}
|
|
4796
|
+
setBusy(key);
|
|
4797
|
+
setLastError(null);
|
|
4798
|
+
try {
|
|
4799
|
+
const outcome = await action(token);
|
|
4800
|
+
reload();
|
|
4801
|
+
return outcome;
|
|
4802
|
+
} catch (cause) {
|
|
4803
|
+
setLastError(codeOf(cause));
|
|
4804
|
+
return null;
|
|
4805
|
+
} finally {
|
|
4806
|
+
setBusy(null);
|
|
4807
|
+
}
|
|
4808
|
+
},
|
|
4809
|
+
[token, reload]
|
|
4810
|
+
);
|
|
4811
|
+
return {
|
|
4812
|
+
attached,
|
|
4813
|
+
available,
|
|
4814
|
+
loading: Boolean(token) && loading2,
|
|
4815
|
+
lastError,
|
|
4816
|
+
busy,
|
|
4817
|
+
signedIn: Boolean(token),
|
|
4818
|
+
attach: (addonId, quantity) => run(
|
|
4819
|
+
addonId,
|
|
4820
|
+
(session) => client.billing.attachAddon(session, {
|
|
4821
|
+
addonId,
|
|
4822
|
+
...quantity === void 0 ? {} : { quantity }
|
|
4823
|
+
})
|
|
4824
|
+
),
|
|
4825
|
+
setQuantity: (attachmentId, quantity) => run(
|
|
4826
|
+
attachmentId,
|
|
4827
|
+
(session) => client.billing.setAddonQuantity(session, attachmentId, quantity)
|
|
4828
|
+
),
|
|
4829
|
+
remove: (attachmentId) => run(attachmentId, (session) => client.billing.removeAddon(session, attachmentId)),
|
|
4830
|
+
reload
|
|
4831
|
+
};
|
|
4832
|
+
}
|
|
4833
|
+
|
|
4665
4834
|
// src/DataTable.tsx
|
|
4666
4835
|
import { specFor as specFor3 } from "@base316/sdk";
|
|
4667
|
-
import { useState as
|
|
4836
|
+
import { useState as useState29 } from "react";
|
|
4668
4837
|
|
|
4669
4838
|
// src/fields.tsx
|
|
4670
4839
|
import {
|
|
4671
4840
|
formatAddress,
|
|
4672
4841
|
specFor
|
|
4673
4842
|
} from "@base316/sdk";
|
|
4674
|
-
import { jsx as
|
|
4843
|
+
import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
4675
4844
|
function formatNumber(value, fraction = 0) {
|
|
4676
4845
|
const number = Number(value);
|
|
4677
4846
|
return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
|
|
@@ -4693,10 +4862,10 @@ function formatDuration(value) {
|
|
|
4693
4862
|
}
|
|
4694
4863
|
function FieldCell({ value, field, related }) {
|
|
4695
4864
|
if (field.type === "RELATION") {
|
|
4696
|
-
return related?.title ?? (related?.id ? /* @__PURE__ */
|
|
4865
|
+
return related?.title ?? (related?.id ? /* @__PURE__ */ jsx28("code", { className: "b316-muted", children: related.id }) : "\u2014");
|
|
4697
4866
|
}
|
|
4698
4867
|
if (value === null || value === void 0 || value === "") {
|
|
4699
|
-
return /* @__PURE__ */
|
|
4868
|
+
return /* @__PURE__ */ jsx28("span", { className: "b316-muted", children: "\u2014" });
|
|
4700
4869
|
}
|
|
4701
4870
|
switch (field.type) {
|
|
4702
4871
|
case "BOOLEAN":
|
|
@@ -4711,7 +4880,7 @@ function FieldCell({ value, field, related }) {
|
|
|
4711
4880
|
const stars = Math.round(Number(value));
|
|
4712
4881
|
return /* @__PURE__ */ jsxs26("span", { "aria-label": `${stars} out of 5`, children: [
|
|
4713
4882
|
"\u2605".repeat(stars),
|
|
4714
|
-
/* @__PURE__ */
|
|
4883
|
+
/* @__PURE__ */ jsx28("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
|
|
4715
4884
|
] });
|
|
4716
4885
|
}
|
|
4717
4886
|
case "DATE":
|
|
@@ -4719,15 +4888,15 @@ function FieldCell({ value, field, related }) {
|
|
|
4719
4888
|
case "DATETIME":
|
|
4720
4889
|
return new Date(String(value)).toLocaleString();
|
|
4721
4890
|
case "SELECT":
|
|
4722
|
-
return /* @__PURE__ */
|
|
4891
|
+
return /* @__PURE__ */ jsx28("span", { className: "b316-chip", children: String(value) });
|
|
4723
4892
|
case "MULTISELECT":
|
|
4724
|
-
return /* @__PURE__ */
|
|
4893
|
+
return /* @__PURE__ */ jsx28("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx28("span", { className: "b316-chip", children: String(item) }, String(item))) });
|
|
4725
4894
|
case "URL":
|
|
4726
|
-
return /* @__PURE__ */
|
|
4895
|
+
return /* @__PURE__ */ jsx28("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
|
|
4727
4896
|
case "EMAIL":
|
|
4728
|
-
return /* @__PURE__ */
|
|
4897
|
+
return /* @__PURE__ */ jsx28("a", { href: `mailto:${String(value)}`, children: String(value) });
|
|
4729
4898
|
case "PHONE":
|
|
4730
|
-
return /* @__PURE__ */
|
|
4899
|
+
return /* @__PURE__ */ jsx28("a", { href: `tel:${String(value)}`, children: String(value) });
|
|
4731
4900
|
case "ADDRESS":
|
|
4732
4901
|
return formatAddress(value);
|
|
4733
4902
|
case "ATTACHMENT": {
|
|
@@ -4739,7 +4908,7 @@ function FieldCell({ value, field, related }) {
|
|
|
4739
4908
|
return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
|
|
4740
4909
|
}
|
|
4741
4910
|
case "JSON":
|
|
4742
|
-
return /* @__PURE__ */
|
|
4911
|
+
return /* @__PURE__ */ jsx28("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
|
|
4743
4912
|
default:
|
|
4744
4913
|
return String(value);
|
|
4745
4914
|
}
|
|
@@ -4760,7 +4929,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4760
4929
|
function control() {
|
|
4761
4930
|
switch (field.type) {
|
|
4762
4931
|
case "LONGTEXT":
|
|
4763
|
-
return /* @__PURE__ */
|
|
4932
|
+
return /* @__PURE__ */ jsx28(
|
|
4764
4933
|
"textarea",
|
|
4765
4934
|
{
|
|
4766
4935
|
...common,
|
|
@@ -4770,7 +4939,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4770
4939
|
}
|
|
4771
4940
|
);
|
|
4772
4941
|
case "BOOLEAN":
|
|
4773
|
-
return /* @__PURE__ */
|
|
4942
|
+
return /* @__PURE__ */ jsx28(
|
|
4774
4943
|
"input",
|
|
4775
4944
|
{
|
|
4776
4945
|
...common,
|
|
@@ -4788,15 +4957,15 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4788
4957
|
value: value === null || value === void 0 ? "" : String(value),
|
|
4789
4958
|
onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
|
|
4790
4959
|
children: [
|
|
4791
|
-
field.required ? null : /* @__PURE__ */
|
|
4792
|
-
(field.options ?? []).map((option) => /* @__PURE__ */
|
|
4960
|
+
field.required ? null : /* @__PURE__ */ jsx28("option", { value: "", children: "\u2014" }),
|
|
4961
|
+
(field.options ?? []).map((option) => /* @__PURE__ */ jsx28("option", { value: option, children: option }, option))
|
|
4793
4962
|
]
|
|
4794
4963
|
}
|
|
4795
4964
|
);
|
|
4796
4965
|
case "MULTISELECT": {
|
|
4797
4966
|
const selected = new Set(Array.isArray(value) ? value.map(String) : []);
|
|
4798
|
-
return /* @__PURE__ */
|
|
4799
|
-
/* @__PURE__ */
|
|
4967
|
+
return /* @__PURE__ */ jsx28("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs26("label", { className: "b316-choice", children: [
|
|
4968
|
+
/* @__PURE__ */ jsx28(
|
|
4800
4969
|
"input",
|
|
4801
4970
|
{
|
|
4802
4971
|
type: "checkbox",
|
|
@@ -4819,7 +4988,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4819
4988
|
case "NUMBER":
|
|
4820
4989
|
case "MONEY":
|
|
4821
4990
|
case "PERCENT":
|
|
4822
|
-
return /* @__PURE__ */
|
|
4991
|
+
return /* @__PURE__ */ jsx28(
|
|
4823
4992
|
"input",
|
|
4824
4993
|
{
|
|
4825
4994
|
...common,
|
|
@@ -4830,7 +4999,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4830
4999
|
}
|
|
4831
5000
|
);
|
|
4832
5001
|
case "RATING":
|
|
4833
|
-
return /* @__PURE__ */
|
|
5002
|
+
return /* @__PURE__ */ jsx28(
|
|
4834
5003
|
"input",
|
|
4835
5004
|
{
|
|
4836
5005
|
...common,
|
|
@@ -4845,7 +5014,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4845
5014
|
case "DURATION": {
|
|
4846
5015
|
const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
|
|
4847
5016
|
return /* @__PURE__ */ jsxs26("div", { className: "b316-suffixed", children: [
|
|
4848
|
-
/* @__PURE__ */
|
|
5017
|
+
/* @__PURE__ */ jsx28(
|
|
4849
5018
|
"input",
|
|
4850
5019
|
{
|
|
4851
5020
|
...common,
|
|
@@ -4855,11 +5024,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4855
5024
|
onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
|
|
4856
5025
|
}
|
|
4857
5026
|
),
|
|
4858
|
-
/* @__PURE__ */
|
|
5027
|
+
/* @__PURE__ */ jsx28("span", { className: "b316-muted", children: "minutes" })
|
|
4859
5028
|
] });
|
|
4860
5029
|
}
|
|
4861
5030
|
case "DATE":
|
|
4862
|
-
return /* @__PURE__ */
|
|
5031
|
+
return /* @__PURE__ */ jsx28(
|
|
4863
5032
|
"input",
|
|
4864
5033
|
{
|
|
4865
5034
|
...common,
|
|
@@ -4869,7 +5038,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4869
5038
|
}
|
|
4870
5039
|
);
|
|
4871
5040
|
case "DATETIME":
|
|
4872
|
-
return /* @__PURE__ */
|
|
5041
|
+
return /* @__PURE__ */ jsx28(
|
|
4873
5042
|
"input",
|
|
4874
5043
|
{
|
|
4875
5044
|
...common,
|
|
@@ -4882,7 +5051,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4882
5051
|
);
|
|
4883
5052
|
case "ADDRESS": {
|
|
4884
5053
|
const address = value ?? {};
|
|
4885
|
-
const part = (key, label) => /* @__PURE__ */
|
|
5054
|
+
const part = (key, label) => /* @__PURE__ */ jsx28(
|
|
4886
5055
|
"input",
|
|
4887
5056
|
{
|
|
4888
5057
|
className: "b316-input",
|
|
@@ -4904,7 +5073,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4904
5073
|
] });
|
|
4905
5074
|
}
|
|
4906
5075
|
case "EMAIL":
|
|
4907
|
-
return /* @__PURE__ */
|
|
5076
|
+
return /* @__PURE__ */ jsx28(
|
|
4908
5077
|
"input",
|
|
4909
5078
|
{
|
|
4910
5079
|
...common,
|
|
@@ -4914,7 +5083,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4914
5083
|
}
|
|
4915
5084
|
);
|
|
4916
5085
|
case "URL":
|
|
4917
|
-
return /* @__PURE__ */
|
|
5086
|
+
return /* @__PURE__ */ jsx28(
|
|
4918
5087
|
"input",
|
|
4919
5088
|
{
|
|
4920
5089
|
...common,
|
|
@@ -4924,7 +5093,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4924
5093
|
}
|
|
4925
5094
|
);
|
|
4926
5095
|
case "PHONE":
|
|
4927
|
-
return /* @__PURE__ */
|
|
5096
|
+
return /* @__PURE__ */ jsx28(
|
|
4928
5097
|
"input",
|
|
4929
5098
|
{
|
|
4930
5099
|
...common,
|
|
@@ -4934,7 +5103,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4934
5103
|
}
|
|
4935
5104
|
);
|
|
4936
5105
|
default:
|
|
4937
|
-
return /* @__PURE__ */
|
|
5106
|
+
return /* @__PURE__ */ jsx28(
|
|
4938
5107
|
"input",
|
|
4939
5108
|
{
|
|
4940
5109
|
...common,
|
|
@@ -4948,21 +5117,21 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4948
5117
|
return /* @__PURE__ */ jsxs26("div", { className: "b316-field", children: [
|
|
4949
5118
|
/* @__PURE__ */ jsxs26("label", { className: "b316-label", htmlFor: id, children: [
|
|
4950
5119
|
field.label,
|
|
4951
|
-
field.required ? /* @__PURE__ */
|
|
5120
|
+
field.required ? /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4952
5121
|
] }),
|
|
4953
5122
|
control(),
|
|
4954
|
-
field.description ? /* @__PURE__ */
|
|
4955
|
-
error ? /* @__PURE__ */
|
|
5123
|
+
field.description ? /* @__PURE__ */ jsx28("div", { className: "b316-hint", children: field.description }) : null,
|
|
5124
|
+
error ? /* @__PURE__ */ jsx28("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
|
|
4956
5125
|
] });
|
|
4957
5126
|
}
|
|
4958
5127
|
|
|
4959
5128
|
// src/RecordForm.tsx
|
|
4960
5129
|
import { specFor as specFor2 } from "@base316/sdk";
|
|
4961
|
-
import { useEffect as
|
|
5130
|
+
import { useEffect as useEffect24, useState as useState28 } from "react";
|
|
4962
5131
|
|
|
4963
5132
|
// src/RelationPicker.tsx
|
|
4964
|
-
import { useEffect as
|
|
4965
|
-
import { Fragment as Fragment10, jsx as
|
|
5133
|
+
import { useEffect as useEffect22, useRef as useRef8, useState as useState26 } from "react";
|
|
5134
|
+
import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
4966
5135
|
function RelationPicker({
|
|
4967
5136
|
field,
|
|
4968
5137
|
value,
|
|
@@ -4972,13 +5141,13 @@ function RelationPicker({
|
|
|
4972
5141
|
tenant
|
|
4973
5142
|
}) {
|
|
4974
5143
|
const { client, token } = useBase316();
|
|
4975
|
-
const [query, setQuery] =
|
|
4976
|
-
const [results, setResults] =
|
|
4977
|
-
const [chosenTitle, setChosenTitle] =
|
|
4978
|
-
const [open, setOpen] =
|
|
5144
|
+
const [query, setQuery] = useState26("");
|
|
5145
|
+
const [results, setResults] = useState26([]);
|
|
5146
|
+
const [chosenTitle, setChosenTitle] = useState26(null);
|
|
5147
|
+
const [open, setOpen] = useState26(false);
|
|
4979
5148
|
const id = `b316-field-${field.key}`;
|
|
4980
|
-
const box =
|
|
4981
|
-
|
|
5149
|
+
const box = useRef8(null);
|
|
5150
|
+
useEffect22(() => {
|
|
4982
5151
|
if (!token || !value || !field.relationTo) {
|
|
4983
5152
|
setChosenTitle(null);
|
|
4984
5153
|
return;
|
|
@@ -4993,7 +5162,7 @@ function RelationPicker({
|
|
|
4993
5162
|
cancelled = true;
|
|
4994
5163
|
};
|
|
4995
5164
|
}, [client, token, value, field.relationTo, tenant]);
|
|
4996
|
-
|
|
5165
|
+
useEffect22(() => {
|
|
4997
5166
|
if (!token || !field.relationTo || !open) {
|
|
4998
5167
|
return;
|
|
4999
5168
|
}
|
|
@@ -5019,7 +5188,7 @@ function RelationPicker({
|
|
|
5019
5188
|
clearTimeout(timer);
|
|
5020
5189
|
};
|
|
5021
5190
|
}, [client, token, field.relationTo, query, open, tenant]);
|
|
5022
|
-
|
|
5191
|
+
useEffect22(() => {
|
|
5023
5192
|
if (!open || typeof document === "undefined") {
|
|
5024
5193
|
return;
|
|
5025
5194
|
}
|
|
@@ -5036,11 +5205,11 @@ function RelationPicker({
|
|
|
5036
5205
|
return /* @__PURE__ */ jsxs27("div", { className: "b316-field", ref: box, children: [
|
|
5037
5206
|
/* @__PURE__ */ jsxs27("label", { className: "b316-label", htmlFor: id, children: [
|
|
5038
5207
|
field.label,
|
|
5039
|
-
field.required ? /* @__PURE__ */
|
|
5208
|
+
field.required ? /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: " *" }) : null
|
|
5040
5209
|
] }),
|
|
5041
5210
|
value && !open ? /* @__PURE__ */ jsxs27("div", { className: "b316-relation-chosen", children: [
|
|
5042
|
-
/* @__PURE__ */
|
|
5043
|
-
disabled ? null : /* @__PURE__ */
|
|
5211
|
+
/* @__PURE__ */ jsx29("span", { children: chosenTitle ?? value }),
|
|
5212
|
+
disabled ? null : /* @__PURE__ */ jsx29(
|
|
5044
5213
|
"button",
|
|
5045
5214
|
{
|
|
5046
5215
|
type: "button",
|
|
@@ -5052,7 +5221,7 @@ function RelationPicker({
|
|
|
5052
5221
|
children: "Change"
|
|
5053
5222
|
}
|
|
5054
5223
|
),
|
|
5055
|
-
disabled || field.required ? null : /* @__PURE__ */
|
|
5224
|
+
disabled || field.required ? null : /* @__PURE__ */ jsx29(
|
|
5056
5225
|
"button",
|
|
5057
5226
|
{
|
|
5058
5227
|
type: "button",
|
|
@@ -5063,7 +5232,7 @@ function RelationPicker({
|
|
|
5063
5232
|
}
|
|
5064
5233
|
)
|
|
5065
5234
|
] }) : /* @__PURE__ */ jsxs27(Fragment10, { children: [
|
|
5066
|
-
/* @__PURE__ */
|
|
5235
|
+
/* @__PURE__ */ jsx29(
|
|
5067
5236
|
"input",
|
|
5068
5237
|
{
|
|
5069
5238
|
id,
|
|
@@ -5084,7 +5253,7 @@ function RelationPicker({
|
|
|
5084
5253
|
}
|
|
5085
5254
|
}
|
|
5086
5255
|
),
|
|
5087
|
-
open ? /* @__PURE__ */
|
|
5256
|
+
open ? /* @__PURE__ */ jsx29("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx29("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx29("li", { children: /* @__PURE__ */ jsx29(
|
|
5088
5257
|
"button",
|
|
5089
5258
|
{
|
|
5090
5259
|
type: "button",
|
|
@@ -5100,13 +5269,13 @@ function RelationPicker({
|
|
|
5100
5269
|
}
|
|
5101
5270
|
) }, result.id)) }) : null
|
|
5102
5271
|
] }),
|
|
5103
|
-
field.description ? /* @__PURE__ */
|
|
5104
|
-
error ? /* @__PURE__ */
|
|
5272
|
+
field.description ? /* @__PURE__ */ jsx29("div", { className: "b316-hint", children: field.description }) : null,
|
|
5273
|
+
error ? /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) : null
|
|
5105
5274
|
] });
|
|
5106
5275
|
}
|
|
5107
5276
|
|
|
5108
5277
|
// src/useCollection.ts
|
|
5109
|
-
import { useCallback as
|
|
5278
|
+
import { useCallback as useCallback10, useEffect as useEffect23, useMemo as useMemo3, useState as useState27 } from "react";
|
|
5110
5279
|
function fieldErrorFrom(cause) {
|
|
5111
5280
|
const param = cause?.param;
|
|
5112
5281
|
const message = cause instanceof Error ? cause.message : "That value was not accepted.";
|
|
@@ -5114,24 +5283,24 @@ function fieldErrorFrom(cause) {
|
|
|
5114
5283
|
}
|
|
5115
5284
|
function useCollection(collection, options = {}) {
|
|
5116
5285
|
const { client, token } = useBase316();
|
|
5117
|
-
const [schema, setSchema] =
|
|
5118
|
-
const [records, setRecords] =
|
|
5119
|
-
const [error, setError] =
|
|
5120
|
-
const [
|
|
5121
|
-
const [total, setTotal] =
|
|
5122
|
-
const [cursor, setCursor] =
|
|
5123
|
-
const [reloadCount, setReloadCount] =
|
|
5124
|
-
const [search, setSearch] =
|
|
5125
|
-
const [filters, setFilters] =
|
|
5126
|
-
const [sort, setSort] =
|
|
5286
|
+
const [schema, setSchema] = useState27(null);
|
|
5287
|
+
const [records, setRecords] = useState27([]);
|
|
5288
|
+
const [error, setError] = useState27(null);
|
|
5289
|
+
const [loading2, setLoading] = useState27(true);
|
|
5290
|
+
const [total, setTotal] = useState27(0);
|
|
5291
|
+
const [cursor, setCursor] = useState27(null);
|
|
5292
|
+
const [reloadCount, setReloadCount] = useState27(0);
|
|
5293
|
+
const [search, setSearch] = useState27("");
|
|
5294
|
+
const [filters, setFilters] = useState27([]);
|
|
5295
|
+
const [sort, setSort] = useState27(
|
|
5127
5296
|
options.sort ?? null
|
|
5128
5297
|
);
|
|
5129
|
-
const [fieldErrors, setFieldErrors] =
|
|
5130
|
-
const [saving, setSaving] =
|
|
5298
|
+
const [fieldErrors, setFieldErrors] = useState27({});
|
|
5299
|
+
const [saving, setSaving] = useState27(false);
|
|
5131
5300
|
const { tenant, limit, recordId } = options;
|
|
5132
5301
|
const fixedFilters = JSON.stringify(options.filters ?? []);
|
|
5133
5302
|
const scope = useMemo3(() => tenant ? { tenant } : void 0, [tenant]);
|
|
5134
|
-
|
|
5303
|
+
useEffect23(() => {
|
|
5135
5304
|
if (!token) {
|
|
5136
5305
|
return;
|
|
5137
5306
|
}
|
|
@@ -5150,7 +5319,7 @@ function useCollection(collection, options = {}) {
|
|
|
5150
5319
|
cancelled = true;
|
|
5151
5320
|
};
|
|
5152
5321
|
}, [client, token, collection, scope]);
|
|
5153
|
-
|
|
5322
|
+
useEffect23(() => {
|
|
5154
5323
|
if (!token || !schema) {
|
|
5155
5324
|
return;
|
|
5156
5325
|
}
|
|
@@ -5220,10 +5389,10 @@ function useCollection(collection, options = {}) {
|
|
|
5220
5389
|
scope,
|
|
5221
5390
|
reloadCount
|
|
5222
5391
|
]);
|
|
5223
|
-
const reload =
|
|
5392
|
+
const reload = useCallback10(() => {
|
|
5224
5393
|
setReloadCount((count) => count + 1);
|
|
5225
5394
|
}, []);
|
|
5226
|
-
const loadMore =
|
|
5395
|
+
const loadMore = useCallback10(() => {
|
|
5227
5396
|
if (!token || !cursor) {
|
|
5228
5397
|
return;
|
|
5229
5398
|
}
|
|
@@ -5247,7 +5416,7 @@ function useCollection(collection, options = {}) {
|
|
|
5247
5416
|
setLoading(false);
|
|
5248
5417
|
});
|
|
5249
5418
|
}, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
|
|
5250
|
-
const toggleSort =
|
|
5419
|
+
const toggleSort = useCallback10((field) => {
|
|
5251
5420
|
setSort((current) => {
|
|
5252
5421
|
if (current?.field !== field) {
|
|
5253
5422
|
return { field, direction: "asc" };
|
|
@@ -5255,7 +5424,7 @@ function useCollection(collection, options = {}) {
|
|
|
5255
5424
|
return current.direction === "asc" ? { field, direction: "desc" } : null;
|
|
5256
5425
|
});
|
|
5257
5426
|
}, []);
|
|
5258
|
-
const create =
|
|
5427
|
+
const create = useCallback10(
|
|
5259
5428
|
async (fields) => {
|
|
5260
5429
|
if (!token) {
|
|
5261
5430
|
return null;
|
|
@@ -5275,7 +5444,7 @@ function useCollection(collection, options = {}) {
|
|
|
5275
5444
|
},
|
|
5276
5445
|
[client, token, collection, scope, reload]
|
|
5277
5446
|
);
|
|
5278
|
-
const update =
|
|
5447
|
+
const update = useCallback10(
|
|
5279
5448
|
async (id, fields) => {
|
|
5280
5449
|
if (!token) {
|
|
5281
5450
|
return null;
|
|
@@ -5297,7 +5466,7 @@ function useCollection(collection, options = {}) {
|
|
|
5297
5466
|
},
|
|
5298
5467
|
[client, token, collection, scope]
|
|
5299
5468
|
);
|
|
5300
|
-
const remove =
|
|
5469
|
+
const remove = useCallback10(
|
|
5301
5470
|
async (id) => {
|
|
5302
5471
|
if (!token) {
|
|
5303
5472
|
return false;
|
|
@@ -5320,7 +5489,7 @@ function useCollection(collection, options = {}) {
|
|
|
5320
5489
|
return {
|
|
5321
5490
|
schema,
|
|
5322
5491
|
records,
|
|
5323
|
-
loading,
|
|
5492
|
+
loading: loading2,
|
|
5324
5493
|
error,
|
|
5325
5494
|
total,
|
|
5326
5495
|
hasMore: cursor !== null,
|
|
@@ -5342,7 +5511,7 @@ function useCollection(collection, options = {}) {
|
|
|
5342
5511
|
}
|
|
5343
5512
|
|
|
5344
5513
|
// src/RecordForm.tsx
|
|
5345
|
-
import { jsx as
|
|
5514
|
+
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5346
5515
|
function RecordForm({
|
|
5347
5516
|
collection,
|
|
5348
5517
|
recordId,
|
|
@@ -5363,20 +5532,20 @@ function RecordForm({
|
|
|
5363
5532
|
recordId
|
|
5364
5533
|
}
|
|
5365
5534
|
);
|
|
5366
|
-
const [values, setValues] =
|
|
5367
|
-
const [loaded, setLoaded] =
|
|
5535
|
+
const [values, setValues] = useState28(defaults ?? {});
|
|
5536
|
+
const [loaded, setLoaded] = useState28(!recordId);
|
|
5368
5537
|
const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
|
|
5369
|
-
|
|
5538
|
+
useEffect24(() => {
|
|
5370
5539
|
if (existing && !loaded) {
|
|
5371
5540
|
setValues(existing.fields);
|
|
5372
5541
|
setLoaded(true);
|
|
5373
5542
|
}
|
|
5374
5543
|
}, [existing, loaded]);
|
|
5375
5544
|
if (error) {
|
|
5376
|
-
return /* @__PURE__ */
|
|
5545
|
+
return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5377
5546
|
}
|
|
5378
5547
|
if (!schema || !loaded) {
|
|
5379
|
-
return /* @__PURE__ */
|
|
5548
|
+
return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5380
5549
|
}
|
|
5381
5550
|
const editable = schema.fields.filter((field) => !specFor2(field).computed);
|
|
5382
5551
|
async function submit(event) {
|
|
@@ -5387,10 +5556,10 @@ function RecordForm({
|
|
|
5387
5556
|
}
|
|
5388
5557
|
}
|
|
5389
5558
|
return /* @__PURE__ */ jsxs28("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
5390
|
-
/* @__PURE__ */
|
|
5391
|
-
fieldErrors._ ? /* @__PURE__ */
|
|
5559
|
+
/* @__PURE__ */ jsx30("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
|
|
5560
|
+
fieldErrors._ ? /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
|
|
5392
5561
|
editable.map(
|
|
5393
|
-
(field) => field.type === "RELATION" ? /* @__PURE__ */
|
|
5562
|
+
(field) => field.type === "RELATION" ? /* @__PURE__ */ jsx30(
|
|
5394
5563
|
RelationPicker,
|
|
5395
5564
|
{
|
|
5396
5565
|
field,
|
|
@@ -5401,7 +5570,7 @@ function RecordForm({
|
|
|
5401
5570
|
onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
|
|
5402
5571
|
},
|
|
5403
5572
|
field.key
|
|
5404
|
-
) : /* @__PURE__ */
|
|
5573
|
+
) : /* @__PURE__ */ jsx30(
|
|
5405
5574
|
FieldInput,
|
|
5406
5575
|
{
|
|
5407
5576
|
field,
|
|
@@ -5414,14 +5583,14 @@ function RecordForm({
|
|
|
5414
5583
|
)
|
|
5415
5584
|
),
|
|
5416
5585
|
/* @__PURE__ */ jsxs28("div", { className: "b316-form-actions", children: [
|
|
5417
|
-
onCancel ? /* @__PURE__ */
|
|
5418
|
-
/* @__PURE__ */
|
|
5586
|
+
onCancel ? /* @__PURE__ */ jsx30("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
|
|
5587
|
+
/* @__PURE__ */ jsx30("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
|
|
5419
5588
|
] })
|
|
5420
5589
|
] });
|
|
5421
5590
|
}
|
|
5422
5591
|
|
|
5423
5592
|
// src/DataTable.tsx
|
|
5424
|
-
import { jsx as
|
|
5593
|
+
import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5425
5594
|
function DataTable({
|
|
5426
5595
|
collection,
|
|
5427
5596
|
columns,
|
|
@@ -5438,7 +5607,7 @@ function DataTable({
|
|
|
5438
5607
|
const {
|
|
5439
5608
|
schema,
|
|
5440
5609
|
records,
|
|
5441
|
-
loading,
|
|
5610
|
+
loading: loading2,
|
|
5442
5611
|
error,
|
|
5443
5612
|
total,
|
|
5444
5613
|
hasMore,
|
|
@@ -5450,13 +5619,13 @@ function DataTable({
|
|
|
5450
5619
|
loadMore,
|
|
5451
5620
|
remove
|
|
5452
5621
|
} = useCollection(collection, options);
|
|
5453
|
-
const [editing, setEditing] =
|
|
5454
|
-
const [removeFailed, setRemoveFailed] =
|
|
5622
|
+
const [editing, setEditing] = useState29(null);
|
|
5623
|
+
const [removeFailed, setRemoveFailed] = useState29(null);
|
|
5455
5624
|
if (error) {
|
|
5456
|
-
return /* @__PURE__ */
|
|
5625
|
+
return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5457
5626
|
}
|
|
5458
5627
|
if (!schema) {
|
|
5459
|
-
return /* @__PURE__ */
|
|
5628
|
+
return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5460
5629
|
}
|
|
5461
5630
|
const shown = columns ? (
|
|
5462
5631
|
// Ordered by what was asked for, not by the schema: a caller naming
|
|
@@ -5466,9 +5635,9 @@ function DataTable({
|
|
|
5466
5635
|
const searchable = schema.fields.some((field) => specFor3(field).capabilities.searchable);
|
|
5467
5636
|
const writable = canWrite && !readOnly;
|
|
5468
5637
|
return /* @__PURE__ */ jsxs29("div", { className: cls("b316-table-wrap", className), style, children: [
|
|
5469
|
-
removeFailed ? /* @__PURE__ */
|
|
5638
|
+
removeFailed ? /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
|
|
5470
5639
|
/* @__PURE__ */ jsxs29("div", { className: "b316-table-bar", children: [
|
|
5471
|
-
searchable && !hideSearch ? /* @__PURE__ */
|
|
5640
|
+
searchable && !hideSearch ? /* @__PURE__ */ jsx31(
|
|
5472
5641
|
"input",
|
|
5473
5642
|
{
|
|
5474
5643
|
type: "search",
|
|
@@ -5478,7 +5647,7 @@ function DataTable({
|
|
|
5478
5647
|
value: search,
|
|
5479
5648
|
onChange: (event) => setSearch(event.target.value)
|
|
5480
5649
|
}
|
|
5481
|
-
) : /* @__PURE__ */
|
|
5650
|
+
) : /* @__PURE__ */ jsx31("span", {}),
|
|
5482
5651
|
/* @__PURE__ */ jsxs29("div", { className: "b316-table-actions", children: [
|
|
5483
5652
|
/* @__PURE__ */ jsxs29("span", { className: "b316-muted", children: [
|
|
5484
5653
|
total,
|
|
@@ -5491,12 +5660,12 @@ function DataTable({
|
|
|
5491
5660
|
] }) : null
|
|
5492
5661
|
] })
|
|
5493
5662
|
] }),
|
|
5494
|
-
/* @__PURE__ */
|
|
5495
|
-
/* @__PURE__ */
|
|
5663
|
+
/* @__PURE__ */ jsx31("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
|
|
5664
|
+
/* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
|
|
5496
5665
|
shown.map((field) => {
|
|
5497
5666
|
const sortable = specFor3(field).capabilities.sortable;
|
|
5498
5667
|
const active = sort?.field === field.key;
|
|
5499
|
-
return /* @__PURE__ */
|
|
5668
|
+
return /* @__PURE__ */ jsx31("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs29(
|
|
5500
5669
|
"button",
|
|
5501
5670
|
{
|
|
5502
5671
|
type: "button",
|
|
@@ -5504,20 +5673,20 @@ function DataTable({
|
|
|
5504
5673
|
onClick: () => toggleSort(field.key),
|
|
5505
5674
|
children: [
|
|
5506
5675
|
field.label,
|
|
5507
|
-
/* @__PURE__ */
|
|
5676
|
+
/* @__PURE__ */ jsx31("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
|
|
5508
5677
|
]
|
|
5509
5678
|
}
|
|
5510
5679
|
) : field.label }, field.key);
|
|
5511
5680
|
}),
|
|
5512
|
-
writable ? /* @__PURE__ */
|
|
5681
|
+
writable ? /* @__PURE__ */ jsx31("th", { scope: "col", className: "b316-table-rowactions" }) : null
|
|
5513
5682
|
] }) }),
|
|
5514
|
-
/* @__PURE__ */
|
|
5683
|
+
/* @__PURE__ */ jsx31("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs29(
|
|
5515
5684
|
"tr",
|
|
5516
5685
|
{
|
|
5517
5686
|
className: onSelect ? "b316-row-clickable" : void 0,
|
|
5518
5687
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5519
5688
|
children: [
|
|
5520
|
-
shown.map((field) => /* @__PURE__ */
|
|
5689
|
+
shown.map((field) => /* @__PURE__ */ jsx31("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx31(
|
|
5521
5690
|
FieldCell,
|
|
5522
5691
|
{
|
|
5523
5692
|
value: record.fields[field.key] ?? null,
|
|
@@ -5526,7 +5695,7 @@ function DataTable({
|
|
|
5526
5695
|
}
|
|
5527
5696
|
) }, field.key)),
|
|
5528
5697
|
writable ? /* @__PURE__ */ jsxs29("td", { className: "b316-table-rowactions", children: [
|
|
5529
|
-
/* @__PURE__ */
|
|
5698
|
+
/* @__PURE__ */ jsx31(
|
|
5530
5699
|
"button",
|
|
5531
5700
|
{
|
|
5532
5701
|
type: "button",
|
|
@@ -5538,7 +5707,7 @@ function DataTable({
|
|
|
5538
5707
|
children: "Edit"
|
|
5539
5708
|
}
|
|
5540
5709
|
),
|
|
5541
|
-
/* @__PURE__ */
|
|
5710
|
+
/* @__PURE__ */ jsx31(
|
|
5542
5711
|
ConfirmButton,
|
|
5543
5712
|
{
|
|
5544
5713
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5562,10 +5731,10 @@ function DataTable({
|
|
|
5562
5731
|
record.id
|
|
5563
5732
|
)) })
|
|
5564
5733
|
] }) }),
|
|
5565
|
-
records.length === 0 && !
|
|
5566
|
-
|
|
5567
|
-
hasMore ? /* @__PURE__ */
|
|
5568
|
-
editing ? /* @__PURE__ */
|
|
5734
|
+
records.length === 0 && !loading2 ? /* @__PURE__ */ jsx31("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
|
|
5735
|
+
loading2 ? /* @__PURE__ */ jsx31("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
|
|
5736
|
+
hasMore ? /* @__PURE__ */ jsx31("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading2, children: "Load more" }) }) : null,
|
|
5737
|
+
editing ? /* @__PURE__ */ jsx31(
|
|
5569
5738
|
RecordForm,
|
|
5570
5739
|
{
|
|
5571
5740
|
collection,
|
|
@@ -5593,8 +5762,8 @@ import {
|
|
|
5593
5762
|
specFor as specFor4,
|
|
5594
5763
|
titleFieldOf
|
|
5595
5764
|
} from "@base316/sdk";
|
|
5596
|
-
import { useState as
|
|
5597
|
-
import { jsx as
|
|
5765
|
+
import { useState as useState30 } from "react";
|
|
5766
|
+
import { jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5598
5767
|
function Kanban({
|
|
5599
5768
|
collection,
|
|
5600
5769
|
groupBy,
|
|
@@ -5605,23 +5774,23 @@ function Kanban({
|
|
|
5605
5774
|
style,
|
|
5606
5775
|
...options
|
|
5607
5776
|
}) {
|
|
5608
|
-
const { schema, records, loading, error, canWrite, update, total, hasMore, loadMore } = useCollection(collection, {
|
|
5777
|
+
const { schema, records, loading: loading2, error, canWrite, update, total, hasMore, loadMore } = useCollection(collection, {
|
|
5609
5778
|
// A board shows everything at once by its nature — a column holding the
|
|
5610
5779
|
// first twenty-five of two hundred is misleading rather than partial.
|
|
5611
5780
|
limit: options.limit ?? 100,
|
|
5612
5781
|
...options
|
|
5613
5782
|
});
|
|
5614
|
-
const [dragging, setDragging] =
|
|
5615
|
-
const [over, setOver] =
|
|
5783
|
+
const [dragging, setDragging] = useState30(null);
|
|
5784
|
+
const [over, setOver] = useState30(null);
|
|
5616
5785
|
if (error) {
|
|
5617
|
-
return /* @__PURE__ */
|
|
5786
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5618
5787
|
}
|
|
5619
5788
|
if (!schema) {
|
|
5620
|
-
return /* @__PURE__ */
|
|
5789
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5621
5790
|
}
|
|
5622
5791
|
const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : defaultGroupFieldOf(schema.fields);
|
|
5623
5792
|
if (!field || !specFor4(field).capabilities.groupable) {
|
|
5624
|
-
return /* @__PURE__ */
|
|
5793
|
+
return /* @__PURE__ */ jsx32("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.` });
|
|
5625
5794
|
}
|
|
5626
5795
|
const columns = columnsFor(field);
|
|
5627
5796
|
const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
|
|
@@ -5639,7 +5808,7 @@ function Kanban({
|
|
|
5639
5808
|
await update(record.id, { [field.key]: value });
|
|
5640
5809
|
}
|
|
5641
5810
|
return /* @__PURE__ */ jsxs30("div", { className: cls("b316-board-wrap", className), style, children: [
|
|
5642
|
-
/* @__PURE__ */
|
|
5811
|
+
/* @__PURE__ */ jsx32("div", { className: "b316-board", role: "list", children: columns.map((column) => {
|
|
5643
5812
|
const inColumn = records.filter(
|
|
5644
5813
|
(record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
|
|
5645
5814
|
);
|
|
@@ -5668,8 +5837,8 @@ function Kanban({
|
|
|
5668
5837
|
},
|
|
5669
5838
|
children: [
|
|
5670
5839
|
/* @__PURE__ */ jsxs30("header", { className: "b316-board-head", children: [
|
|
5671
|
-
/* @__PURE__ */
|
|
5672
|
-
/* @__PURE__ */
|
|
5840
|
+
/* @__PURE__ */ jsx32("span", { className: "b316-board-title", children: column.label }),
|
|
5841
|
+
/* @__PURE__ */ jsx32("span", { className: "b316-muted", children: inColumn.length })
|
|
5673
5842
|
] }),
|
|
5674
5843
|
/* @__PURE__ */ jsxs30("div", { className: "b316-board-cards", children: [
|
|
5675
5844
|
inColumn.map((record) => /* @__PURE__ */ jsxs30(
|
|
@@ -5684,10 +5853,10 @@ function Kanban({
|
|
|
5684
5853
|
},
|
|
5685
5854
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5686
5855
|
children: [
|
|
5687
|
-
/* @__PURE__ */
|
|
5856
|
+
/* @__PURE__ */ jsx32("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
|
|
5688
5857
|
shown.map((candidate) => /* @__PURE__ */ jsxs30("div", { className: "b316-board-card-field", children: [
|
|
5689
|
-
/* @__PURE__ */
|
|
5690
|
-
/* @__PURE__ */
|
|
5858
|
+
/* @__PURE__ */ jsx32("span", { className: "b316-muted", children: candidate.label }),
|
|
5859
|
+
/* @__PURE__ */ jsx32(
|
|
5691
5860
|
FieldCell,
|
|
5692
5861
|
{
|
|
5693
5862
|
value: record.fields[candidate.key] ?? null,
|
|
@@ -5701,8 +5870,8 @@ function Kanban({
|
|
|
5701
5870
|
// phone. This is the same action by other means, not a
|
|
5702
5871
|
// lesser fallback.
|
|
5703
5872
|
/* @__PURE__ */ jsxs30("label", { className: "b316-board-move", children: [
|
|
5704
|
-
/* @__PURE__ */
|
|
5705
|
-
/* @__PURE__ */
|
|
5873
|
+
/* @__PURE__ */ jsx32("span", { className: "b316-muted", children: "Move to" }),
|
|
5874
|
+
/* @__PURE__ */ jsx32(
|
|
5706
5875
|
"select",
|
|
5707
5876
|
{
|
|
5708
5877
|
className: "b316-input",
|
|
@@ -5714,7 +5883,7 @@ function Kanban({
|
|
|
5714
5883
|
);
|
|
5715
5884
|
void move(record, chosen?.value ?? null);
|
|
5716
5885
|
},
|
|
5717
|
-
children: columns.map((candidate) => /* @__PURE__ */
|
|
5886
|
+
children: columns.map((candidate) => /* @__PURE__ */ jsx32("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
|
|
5718
5887
|
}
|
|
5719
5888
|
)
|
|
5720
5889
|
] })
|
|
@@ -5723,14 +5892,14 @@ function Kanban({
|
|
|
5723
5892
|
},
|
|
5724
5893
|
record.id
|
|
5725
5894
|
)),
|
|
5726
|
-
inColumn.length === 0 ? /* @__PURE__ */
|
|
5895
|
+
inColumn.length === 0 ? /* @__PURE__ */ jsx32("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
|
|
5727
5896
|
] })
|
|
5728
5897
|
]
|
|
5729
5898
|
},
|
|
5730
5899
|
String(column.value)
|
|
5731
5900
|
);
|
|
5732
5901
|
}) }),
|
|
5733
|
-
hasMore ? /* @__PURE__ */
|
|
5902
|
+
hasMore ? /* @__PURE__ */ jsx32("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs30("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading2, children: [
|
|
5734
5903
|
"Showing ",
|
|
5735
5904
|
records.length,
|
|
5736
5905
|
" of ",
|
|
@@ -5757,7 +5926,7 @@ import {
|
|
|
5757
5926
|
specFor as specFor5
|
|
5758
5927
|
} from "@base316/sdk";
|
|
5759
5928
|
import { useMemo as useMemo4 } from "react";
|
|
5760
|
-
import { jsx as
|
|
5929
|
+
import { jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5761
5930
|
function Chart({
|
|
5762
5931
|
collection,
|
|
5763
5932
|
x,
|
|
@@ -5770,7 +5939,7 @@ function Chart({
|
|
|
5770
5939
|
style,
|
|
5771
5940
|
...options
|
|
5772
5941
|
}) {
|
|
5773
|
-
const { schema, records, error, loading } = useCollection(collection, {
|
|
5942
|
+
const { schema, records, error, loading: loading2 } = useCollection(collection, {
|
|
5774
5943
|
// A chart of one page is a chart of an arbitrary subset, which is worse
|
|
5775
5944
|
// than no chart: it looks like an answer.
|
|
5776
5945
|
limit: options.limit ?? 200,
|
|
@@ -5796,23 +5965,23 @@ function Chart({
|
|
|
5796
5965
|
[records, axis, measure, aggregate, bucket, y]
|
|
5797
5966
|
);
|
|
5798
5967
|
if (error) {
|
|
5799
|
-
return /* @__PURE__ */
|
|
5968
|
+
return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5800
5969
|
}
|
|
5801
|
-
if (!schema ||
|
|
5802
|
-
return /* @__PURE__ */
|
|
5970
|
+
if (!schema || loading2) {
|
|
5971
|
+
return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5803
5972
|
}
|
|
5804
5973
|
if (!axis) {
|
|
5805
|
-
return /* @__PURE__ */
|
|
5974
|
+
return /* @__PURE__ */ jsx33("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.` });
|
|
5806
5975
|
}
|
|
5807
5976
|
if (y && !measure) {
|
|
5808
|
-
return /* @__PURE__ */
|
|
5977
|
+
return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
|
|
5809
5978
|
}
|
|
5810
5979
|
const peak = Math.max(...buckets.map((entry) => entry.value), 0);
|
|
5811
5980
|
const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
|
|
5812
5981
|
return /* @__PURE__ */ jsxs31("figure", { className: cls("b316-card b316-chart", className), style, children: [
|
|
5813
|
-
/* @__PURE__ */
|
|
5814
|
-
buckets.length === 0 || peak === 0 ? /* @__PURE__ */
|
|
5815
|
-
/* @__PURE__ */
|
|
5982
|
+
/* @__PURE__ */ jsx33("figcaption", { className: "b316-chart-title", children: heading }),
|
|
5983
|
+
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx33("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx33("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs31("div", { className: "b316-chart-col", children: [
|
|
5984
|
+
/* @__PURE__ */ jsx33(
|
|
5816
5985
|
"div",
|
|
5817
5986
|
{
|
|
5818
5987
|
className: "b316-chart-bar",
|
|
@@ -5820,18 +5989,18 @@ function Chart({
|
|
|
5820
5989
|
title: `${entry.label}: ${format(entry.value)}`
|
|
5821
5990
|
}
|
|
5822
5991
|
),
|
|
5823
|
-
/* @__PURE__ */
|
|
5992
|
+
/* @__PURE__ */ jsx33("span", { className: "b316-chart-label", children: entry.label })
|
|
5824
5993
|
] }, entry.key)) }),
|
|
5825
5994
|
/* @__PURE__ */ jsxs31("details", { className: "b316-chart-data", children: [
|
|
5826
|
-
/* @__PURE__ */
|
|
5995
|
+
/* @__PURE__ */ jsx33("summary", { children: "Values" }),
|
|
5827
5996
|
/* @__PURE__ */ jsxs31("table", { className: "b316-table", children: [
|
|
5828
|
-
/* @__PURE__ */
|
|
5829
|
-
/* @__PURE__ */
|
|
5830
|
-
/* @__PURE__ */
|
|
5997
|
+
/* @__PURE__ */ jsx33("thead", { children: /* @__PURE__ */ jsxs31("tr", { children: [
|
|
5998
|
+
/* @__PURE__ */ jsx33("th", { scope: "col", children: axis.label }),
|
|
5999
|
+
/* @__PURE__ */ jsx33("th", { scope: "col", children: measure ? measure.label : "Count" })
|
|
5831
6000
|
] }) }),
|
|
5832
|
-
/* @__PURE__ */
|
|
5833
|
-
/* @__PURE__ */
|
|
5834
|
-
/* @__PURE__ */
|
|
6001
|
+
/* @__PURE__ */ jsx33("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs31("tr", { children: [
|
|
6002
|
+
/* @__PURE__ */ jsx33("td", { children: entry.label }),
|
|
6003
|
+
/* @__PURE__ */ jsx33("td", { children: format(entry.value) })
|
|
5835
6004
|
] }, entry.key)) })
|
|
5836
6005
|
] })
|
|
5837
6006
|
] })
|
|
@@ -5890,8 +6059,8 @@ function combine(values, aggregate) {
|
|
|
5890
6059
|
|
|
5891
6060
|
// src/RecordDetail.tsx
|
|
5892
6061
|
import { specFor as specFor6 } from "@base316/sdk";
|
|
5893
|
-
import { useState as
|
|
5894
|
-
import { jsx as
|
|
6062
|
+
import { useState as useState31 } from "react";
|
|
6063
|
+
import { jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5895
6064
|
function RecordDetail({
|
|
5896
6065
|
collection,
|
|
5897
6066
|
recordId,
|
|
@@ -5903,17 +6072,17 @@ function RecordDetail({
|
|
|
5903
6072
|
className,
|
|
5904
6073
|
style
|
|
5905
6074
|
}) {
|
|
5906
|
-
const { schema, records, canWrite, remove, loading, error } = useCollection(collection, {
|
|
6075
|
+
const { schema, records, canWrite, remove, loading: loading2, error } = useCollection(collection, {
|
|
5907
6076
|
tenant,
|
|
5908
6077
|
recordId
|
|
5909
6078
|
});
|
|
5910
|
-
const [editing, setEditing] =
|
|
6079
|
+
const [editing, setEditing] = useState31(false);
|
|
5911
6080
|
const record = records.find((candidate) => candidate.id === recordId);
|
|
5912
6081
|
if (error) {
|
|
5913
|
-
return /* @__PURE__ */
|
|
6082
|
+
return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5914
6083
|
}
|
|
5915
|
-
if (!schema ||
|
|
5916
|
-
return /* @__PURE__ */
|
|
6084
|
+
if (!schema || loading2) {
|
|
6085
|
+
return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5917
6086
|
}
|
|
5918
6087
|
if (!record) {
|
|
5919
6088
|
return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card", className), style, children: [
|
|
@@ -5923,7 +6092,7 @@ function RecordDetail({
|
|
|
5923
6092
|
] });
|
|
5924
6093
|
}
|
|
5925
6094
|
if (editing) {
|
|
5926
|
-
return /* @__PURE__ */
|
|
6095
|
+
return /* @__PURE__ */ jsx34(
|
|
5927
6096
|
RecordForm,
|
|
5928
6097
|
{
|
|
5929
6098
|
collection,
|
|
@@ -5939,10 +6108,10 @@ function RecordDetail({
|
|
|
5939
6108
|
const writable = canWrite && !readOnly;
|
|
5940
6109
|
return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card b316-detail", className), style, children: [
|
|
5941
6110
|
/* @__PURE__ */ jsxs32("div", { className: "b316-detail-head", children: [
|
|
5942
|
-
/* @__PURE__ */
|
|
6111
|
+
/* @__PURE__ */ jsx34("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
|
|
5943
6112
|
/* @__PURE__ */ jsxs32("div", { className: "b316-detail-actions", children: [
|
|
5944
|
-
writable ? /* @__PURE__ */
|
|
5945
|
-
writable ? /* @__PURE__ */
|
|
6113
|
+
writable ? /* @__PURE__ */ jsx34("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
|
|
6114
|
+
writable ? /* @__PURE__ */ jsx34(
|
|
5946
6115
|
ConfirmButton,
|
|
5947
6116
|
{
|
|
5948
6117
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5955,15 +6124,15 @@ function RecordDetail({
|
|
|
5955
6124
|
children: "Delete"
|
|
5956
6125
|
}
|
|
5957
6126
|
) : null,
|
|
5958
|
-
onClose ? /* @__PURE__ */
|
|
6127
|
+
onClose ? /* @__PURE__ */ jsx34("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
|
|
5959
6128
|
] })
|
|
5960
6129
|
] }),
|
|
5961
|
-
/* @__PURE__ */
|
|
6130
|
+
/* @__PURE__ */ jsx34("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs32("div", { className: "b316-detail-row", children: [
|
|
5962
6131
|
/* @__PURE__ */ jsxs32("dt", { className: "b316-label", children: [
|
|
5963
6132
|
field.label,
|
|
5964
|
-
specFor6(field).computed ? /* @__PURE__ */
|
|
6133
|
+
specFor6(field).computed ? /* @__PURE__ */ jsx34("span", { className: "b316-muted", children: " (calculated)" }) : null
|
|
5965
6134
|
] }),
|
|
5966
|
-
/* @__PURE__ */
|
|
6135
|
+
/* @__PURE__ */ jsx34("dd", { children: /* @__PURE__ */ jsx34(
|
|
5967
6136
|
FieldCell,
|
|
5968
6137
|
{
|
|
5969
6138
|
value: record.fields[field.key] ?? null,
|
|
@@ -5977,8 +6146,8 @@ function RecordDetail({
|
|
|
5977
6146
|
}
|
|
5978
6147
|
|
|
5979
6148
|
// src/SubscriptionManager.tsx
|
|
5980
|
-
import { useCallback as
|
|
5981
|
-
import { jsx as
|
|
6149
|
+
import { useCallback as useCallback11, useEffect as useEffect25, useState as useState32 } from "react";
|
|
6150
|
+
import { jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5982
6151
|
function statusLabel(status2) {
|
|
5983
6152
|
const words = status2.toLowerCase().split("_");
|
|
5984
6153
|
return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
|
|
@@ -6018,16 +6187,16 @@ function SubscriptionManager({
|
|
|
6018
6187
|
style
|
|
6019
6188
|
}) {
|
|
6020
6189
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6021
|
-
const [subscription, setSubscription] =
|
|
6022
|
-
const [
|
|
6023
|
-
const [managedBy, setManagedBy] =
|
|
6024
|
-
const [schedule, setSchedule] =
|
|
6025
|
-
const [busy, setBusy] =
|
|
6026
|
-
const [error, setError] =
|
|
6027
|
-
const [step, setStep] =
|
|
6028
|
-
const [reason, setReason] =
|
|
6029
|
-
const [comment, setComment] =
|
|
6030
|
-
const load =
|
|
6190
|
+
const [subscription, setSubscription] = useState32(null);
|
|
6191
|
+
const [loading2, setLoading] = useState32(true);
|
|
6192
|
+
const [managedBy, setManagedBy] = useState32(null);
|
|
6193
|
+
const [schedule, setSchedule] = useState32([]);
|
|
6194
|
+
const [busy, setBusy] = useState32(false);
|
|
6195
|
+
const [error, setError] = useState32(null);
|
|
6196
|
+
const [step, setStep] = useState32({ kind: "idle" });
|
|
6197
|
+
const [reason, setReason] = useState32(null);
|
|
6198
|
+
const [comment, setComment] = useState32("");
|
|
6199
|
+
const load = useCallback11(async () => {
|
|
6031
6200
|
if (!token) {
|
|
6032
6201
|
setSubscription(null);
|
|
6033
6202
|
setLoading(false);
|
|
@@ -6045,7 +6214,7 @@ function SubscriptionManager({
|
|
|
6045
6214
|
setLoading(false);
|
|
6046
6215
|
}
|
|
6047
6216
|
}, [client, token]);
|
|
6048
|
-
|
|
6217
|
+
useEffect25(() => {
|
|
6049
6218
|
void load();
|
|
6050
6219
|
}, [load]);
|
|
6051
6220
|
const act = async (change, failure) => {
|
|
@@ -6062,24 +6231,24 @@ function SubscriptionManager({
|
|
|
6062
6231
|
setBusy(false);
|
|
6063
6232
|
}
|
|
6064
6233
|
};
|
|
6065
|
-
if (sessionLoading ||
|
|
6066
|
-
return /* @__PURE__ */
|
|
6234
|
+
if (sessionLoading || loading2) {
|
|
6235
|
+
return /* @__PURE__ */ jsx35("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
6067
6236
|
}
|
|
6068
6237
|
if (!token) {
|
|
6069
|
-
return /* @__PURE__ */
|
|
6238
|
+
return /* @__PURE__ */ jsx35("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
|
|
6070
6239
|
}
|
|
6071
6240
|
if (error) {
|
|
6072
|
-
return /* @__PURE__ */
|
|
6241
|
+
return /* @__PURE__ */ jsx35("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) });
|
|
6073
6242
|
}
|
|
6074
6243
|
if (!subscription) {
|
|
6075
|
-
return /* @__PURE__ */
|
|
6244
|
+
return /* @__PURE__ */ jsx35("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
|
|
6076
6245
|
}
|
|
6077
6246
|
const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
|
|
6078
6247
|
const next = schedule[0] ?? null;
|
|
6079
6248
|
const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
|
|
6080
6249
|
return /* @__PURE__ */ jsxs33("div", { className: cls("b316-card", className), style, children: [
|
|
6081
|
-
error ? /* @__PURE__ */
|
|
6082
|
-
/* @__PURE__ */
|
|
6250
|
+
error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6251
|
+
/* @__PURE__ */ jsx35("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
|
|
6083
6252
|
/* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
|
|
6084
6253
|
statusLabel(subscription.status),
|
|
6085
6254
|
" \xB7 ",
|
|
@@ -6093,7 +6262,7 @@ function SubscriptionManager({
|
|
|
6093
6262
|
". You keep ",
|
|
6094
6263
|
subscription.planVersion.plan.name,
|
|
6095
6264
|
" until then.",
|
|
6096
|
-
/* @__PURE__ */
|
|
6265
|
+
/* @__PURE__ */ jsx35("div", { children: /* @__PURE__ */ jsx35(
|
|
6097
6266
|
"button",
|
|
6098
6267
|
{
|
|
6099
6268
|
type: "button",
|
|
@@ -6128,7 +6297,7 @@ function SubscriptionManager({
|
|
|
6128
6297
|
renews,
|
|
6129
6298
|
"."
|
|
6130
6299
|
] }),
|
|
6131
|
-
/* @__PURE__ */
|
|
6300
|
+
/* @__PURE__ */ jsx35(
|
|
6132
6301
|
"button",
|
|
6133
6302
|
{
|
|
6134
6303
|
type: "button",
|
|
@@ -6139,13 +6308,13 @@ function SubscriptionManager({
|
|
|
6139
6308
|
}
|
|
6140
6309
|
)
|
|
6141
6310
|
] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs33("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
|
|
6142
|
-
/* @__PURE__ */
|
|
6143
|
-
/* @__PURE__ */
|
|
6311
|
+
/* @__PURE__ */ jsx35("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
|
|
6312
|
+
/* @__PURE__ */ jsx35("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
|
|
6144
6313
|
step.cancellation.offer,
|
|
6145
6314
|
step.cancellation.currency
|
|
6146
6315
|
)}.` }),
|
|
6147
6316
|
/* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6148
|
-
/* @__PURE__ */
|
|
6317
|
+
/* @__PURE__ */ jsx35(
|
|
6149
6318
|
"button",
|
|
6150
6319
|
{
|
|
6151
6320
|
type: "button",
|
|
@@ -6158,7 +6327,7 @@ function SubscriptionManager({
|
|
|
6158
6327
|
children: busy ? "Working\u2026" : "Accept offer and stay"
|
|
6159
6328
|
}
|
|
6160
6329
|
),
|
|
6161
|
-
/* @__PURE__ */
|
|
6330
|
+
/* @__PURE__ */ jsx35(
|
|
6162
6331
|
"button",
|
|
6163
6332
|
{
|
|
6164
6333
|
type: "button",
|
|
@@ -6203,9 +6372,9 @@ function SubscriptionManager({
|
|
|
6203
6372
|
". It will not renew after that."
|
|
6204
6373
|
] }),
|
|
6205
6374
|
/* @__PURE__ */ jsxs33("fieldset", { className: "b316-fieldset", children: [
|
|
6206
|
-
/* @__PURE__ */
|
|
6375
|
+
/* @__PURE__ */ jsx35("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
|
|
6207
6376
|
REASONS.map((option) => /* @__PURE__ */ jsxs33("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
6208
|
-
/* @__PURE__ */
|
|
6377
|
+
/* @__PURE__ */ jsx35(
|
|
6209
6378
|
"input",
|
|
6210
6379
|
{
|
|
6211
6380
|
type: "radio",
|
|
@@ -6215,12 +6384,12 @@ function SubscriptionManager({
|
|
|
6215
6384
|
onChange: () => setReason(option.value)
|
|
6216
6385
|
}
|
|
6217
6386
|
),
|
|
6218
|
-
/* @__PURE__ */
|
|
6387
|
+
/* @__PURE__ */ jsx35("span", { children: option.label })
|
|
6219
6388
|
] }, option.value))
|
|
6220
6389
|
] }),
|
|
6221
6390
|
/* @__PURE__ */ jsxs33("label", { className: "b316-field", children: [
|
|
6222
|
-
/* @__PURE__ */
|
|
6223
|
-
/* @__PURE__ */
|
|
6391
|
+
/* @__PURE__ */ jsx35("span", { className: "b316-label", children: "Anything else? (optional)" }),
|
|
6392
|
+
/* @__PURE__ */ jsx35(
|
|
6224
6393
|
"textarea",
|
|
6225
6394
|
{
|
|
6226
6395
|
className: "b316-input",
|
|
@@ -6232,7 +6401,7 @@ function SubscriptionManager({
|
|
|
6232
6401
|
)
|
|
6233
6402
|
] }),
|
|
6234
6403
|
/* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6235
|
-
/* @__PURE__ */
|
|
6404
|
+
/* @__PURE__ */ jsx35("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
|
|
6236
6405
|
/* @__PURE__ */ jsxs33(
|
|
6237
6406
|
"button",
|
|
6238
6407
|
{
|
|
@@ -6249,7 +6418,7 @@ function SubscriptionManager({
|
|
|
6249
6418
|
] })
|
|
6250
6419
|
]
|
|
6251
6420
|
}
|
|
6252
|
-
) : /* @__PURE__ */
|
|
6421
|
+
) : /* @__PURE__ */ jsx35("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx35(
|
|
6253
6422
|
"button",
|
|
6254
6423
|
{
|
|
6255
6424
|
type: "button",
|
|
@@ -6267,11 +6436,11 @@ function SubscriptionManager({
|
|
|
6267
6436
|
}
|
|
6268
6437
|
|
|
6269
6438
|
// src/BillingPortal.tsx
|
|
6270
|
-
import { useCallback as
|
|
6439
|
+
import { useCallback as useCallback13, useEffect as useEffect29, useState as useState36 } from "react";
|
|
6271
6440
|
|
|
6272
6441
|
// src/CreditBalances.tsx
|
|
6273
|
-
import { useEffect as
|
|
6274
|
-
import { Fragment as Fragment11, jsx as
|
|
6442
|
+
import { useEffect as useEffect26, useState as useState33 } from "react";
|
|
6443
|
+
import { Fragment as Fragment11, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6275
6444
|
function units(value) {
|
|
6276
6445
|
return value === null ? "Unlimited" : Number(value).toLocaleString("en");
|
|
6277
6446
|
}
|
|
@@ -6306,10 +6475,10 @@ function Feature({
|
|
|
6306
6475
|
}) {
|
|
6307
6476
|
const { client, token } = useBase316();
|
|
6308
6477
|
const setting = feature.autoRecharge;
|
|
6309
|
-
const [busy, setBusy] =
|
|
6310
|
-
const [error, setError] =
|
|
6311
|
-
const [saved, setSaved] =
|
|
6312
|
-
const [pack, setPack] =
|
|
6478
|
+
const [busy, setBusy] = useState33(false);
|
|
6479
|
+
const [error, setError] = useState33(null);
|
|
6480
|
+
const [saved, setSaved] = useState33(null);
|
|
6481
|
+
const [pack, setPack] = useState33(feature.packs[0]?.id ?? "");
|
|
6313
6482
|
const unit = feature.unit ? ` ${feature.unit}` : "";
|
|
6314
6483
|
const warning = status(feature);
|
|
6315
6484
|
const buy = async () => {
|
|
@@ -6364,9 +6533,9 @@ function Feature({
|
|
|
6364
6533
|
}
|
|
6365
6534
|
};
|
|
6366
6535
|
return /* @__PURE__ */ jsxs34("div", { className: "b316-card b316-credit-balance", children: [
|
|
6367
|
-
/* @__PURE__ */
|
|
6536
|
+
/* @__PURE__ */ jsx36("div", { className: "b316-label", children: feature.featureName }),
|
|
6368
6537
|
/* @__PURE__ */ jsxs34("div", { children: [
|
|
6369
|
-
/* @__PURE__ */
|
|
6538
|
+
/* @__PURE__ */ jsx36("strong", { children: units(feature.remaining) }),
|
|
6370
6539
|
unit,
|
|
6371
6540
|
" left"
|
|
6372
6541
|
] }),
|
|
@@ -6377,12 +6546,12 @@ function Feature({
|
|
|
6377
6546
|
units(feature.purchasedRemaining),
|
|
6378
6547
|
" purchased"
|
|
6379
6548
|
] }),
|
|
6380
|
-
warning && !managed ? /* @__PURE__ */
|
|
6381
|
-
error ? /* @__PURE__ */
|
|
6382
|
-
saved ? /* @__PURE__ */
|
|
6549
|
+
warning && !managed ? /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: warning }) : null,
|
|
6550
|
+
error ? /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6551
|
+
saved ? /* @__PURE__ */ jsx36("div", { className: "b316-notice", role: "status", children: saved }) : null,
|
|
6383
6552
|
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs34(Fragment11, { children: [
|
|
6384
6553
|
/* @__PURE__ */ jsxs34("div", { className: "b316-row", style: { marginTop: 12 }, children: [
|
|
6385
|
-
/* @__PURE__ */
|
|
6554
|
+
/* @__PURE__ */ jsx36(
|
|
6386
6555
|
"select",
|
|
6387
6556
|
{
|
|
6388
6557
|
className: "b316-input",
|
|
@@ -6398,7 +6567,7 @@ function Feature({
|
|
|
6398
6567
|
] }, option.id))
|
|
6399
6568
|
}
|
|
6400
6569
|
),
|
|
6401
|
-
/* @__PURE__ */
|
|
6570
|
+
/* @__PURE__ */ jsx36(
|
|
6402
6571
|
"button",
|
|
6403
6572
|
{
|
|
6404
6573
|
type: "button",
|
|
@@ -6411,7 +6580,7 @@ function Feature({
|
|
|
6411
6580
|
] }),
|
|
6412
6581
|
/* @__PURE__ */ jsxs34("form", { onSubmit: save, style: { marginTop: 16 }, children: [
|
|
6413
6582
|
/* @__PURE__ */ jsxs34("label", { className: "b316-checkbox", children: [
|
|
6414
|
-
/* @__PURE__ */
|
|
6583
|
+
/* @__PURE__ */ jsx36("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
|
|
6415
6584
|
" ",
|
|
6416
6585
|
"Buy credits automatically when my balance runs low"
|
|
6417
6586
|
] }),
|
|
@@ -6421,7 +6590,7 @@ function Feature({
|
|
|
6421
6590
|
unit,
|
|
6422
6591
|
" are left"
|
|
6423
6592
|
] }),
|
|
6424
|
-
/* @__PURE__ */
|
|
6593
|
+
/* @__PURE__ */ jsx36(
|
|
6425
6594
|
"input",
|
|
6426
6595
|
{
|
|
6427
6596
|
className: "b316-input",
|
|
@@ -6433,20 +6602,20 @@ function Feature({
|
|
|
6433
6602
|
)
|
|
6434
6603
|
] }),
|
|
6435
6604
|
/* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
|
|
6436
|
-
/* @__PURE__ */
|
|
6437
|
-
/* @__PURE__ */
|
|
6605
|
+
/* @__PURE__ */ jsx36("span", { className: "b316-label", children: "Buy" }),
|
|
6606
|
+
/* @__PURE__ */ jsx36(
|
|
6438
6607
|
"select",
|
|
6439
6608
|
{
|
|
6440
6609
|
className: "b316-input",
|
|
6441
6610
|
name: "creditPackId",
|
|
6442
6611
|
defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
|
|
6443
|
-
children: feature.packs.map((option) => /* @__PURE__ */
|
|
6612
|
+
children: feature.packs.map((option) => /* @__PURE__ */ jsx36("option", { value: option.id, children: option.name }, option.id))
|
|
6444
6613
|
}
|
|
6445
6614
|
)
|
|
6446
6615
|
] }),
|
|
6447
6616
|
/* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
|
|
6448
|
-
/* @__PURE__ */
|
|
6449
|
-
/* @__PURE__ */
|
|
6617
|
+
/* @__PURE__ */ jsx36("span", { className: "b316-label", children: "At most this many times a month" }),
|
|
6618
|
+
/* @__PURE__ */ jsx36(
|
|
6450
6619
|
"input",
|
|
6451
6620
|
{
|
|
6452
6621
|
className: "b316-input",
|
|
@@ -6462,7 +6631,7 @@ function Feature({
|
|
|
6462
6631
|
setting?.currency ?? feature.packs[0]?.currency ?? "USD",
|
|
6463
6632
|
") a month"
|
|
6464
6633
|
] }),
|
|
6465
|
-
/* @__PURE__ */
|
|
6634
|
+
/* @__PURE__ */ jsx36(
|
|
6466
6635
|
"input",
|
|
6467
6636
|
{
|
|
6468
6637
|
className: "b316-input",
|
|
@@ -6472,16 +6641,16 @@ function Feature({
|
|
|
6472
6641
|
}
|
|
6473
6642
|
)
|
|
6474
6643
|
] }),
|
|
6475
|
-
/* @__PURE__ */
|
|
6644
|
+
/* @__PURE__ */ jsx36("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
|
|
6476
6645
|
] })
|
|
6477
6646
|
] })
|
|
6478
6647
|
] });
|
|
6479
6648
|
}
|
|
6480
6649
|
function CreditBalances({ onChange, className, style }) {
|
|
6481
6650
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6482
|
-
const [state, setState] =
|
|
6483
|
-
const [version, setVersion] =
|
|
6484
|
-
|
|
6651
|
+
const [state, setState] = useState33({ kind: "loading" });
|
|
6652
|
+
const [version, setVersion] = useState33(0);
|
|
6653
|
+
useEffect26(() => {
|
|
6485
6654
|
if (!token) return;
|
|
6486
6655
|
let cancelled = false;
|
|
6487
6656
|
client.billing.credits(token).then((credits2) => {
|
|
@@ -6494,11 +6663,11 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6494
6663
|
cancelled = true;
|
|
6495
6664
|
};
|
|
6496
6665
|
}, [client, token, version]);
|
|
6497
|
-
const wrap = (content) => /* @__PURE__ */
|
|
6666
|
+
const wrap = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-credit-balances", className), style, children: content });
|
|
6498
6667
|
if (sessionLoading || !token || state.kind === "loading") return null;
|
|
6499
6668
|
if (state.kind === "error") {
|
|
6500
6669
|
return wrap(
|
|
6501
|
-
/* @__PURE__ */
|
|
6670
|
+
/* @__PURE__ */ jsx36("div", { className: "b316-card", children: /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
|
|
6502
6671
|
);
|
|
6503
6672
|
}
|
|
6504
6673
|
const { credits } = state;
|
|
@@ -6511,7 +6680,7 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6511
6680
|
credits.managedBy.name ?? "the organization that manages it",
|
|
6512
6681
|
", which manages them."
|
|
6513
6682
|
] }) : null,
|
|
6514
|
-
credits.features.map((feature) => /* @__PURE__ */
|
|
6683
|
+
credits.features.map((feature) => /* @__PURE__ */ jsx36(
|
|
6515
6684
|
Feature,
|
|
6516
6685
|
{
|
|
6517
6686
|
feature,
|
|
@@ -6528,19 +6697,19 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6528
6697
|
}
|
|
6529
6698
|
|
|
6530
6699
|
// src/PaymentMethod.tsx
|
|
6531
|
-
import { useEffect as
|
|
6532
|
-
import { Fragment as Fragment12, jsx as
|
|
6700
|
+
import { useEffect as useEffect27, useState as useState34 } from "react";
|
|
6701
|
+
import { Fragment as Fragment12, jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6533
6702
|
function brandName(brand) {
|
|
6534
6703
|
if (!brand) return "Card";
|
|
6535
6704
|
return brand.charAt(0).toUpperCase() + brand.slice(1);
|
|
6536
6705
|
}
|
|
6537
6706
|
function PaymentMethod({ returnUrl, className, style }) {
|
|
6538
6707
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6539
|
-
const [state, setState] =
|
|
6540
|
-
const [busy, setBusy] =
|
|
6541
|
-
const [error, setError] =
|
|
6542
|
-
const [version, setVersion] =
|
|
6543
|
-
|
|
6708
|
+
const [state, setState] = useState34({ kind: "loading" });
|
|
6709
|
+
const [busy, setBusy] = useState34(false);
|
|
6710
|
+
const [error, setError] = useState34(null);
|
|
6711
|
+
const [version, setVersion] = useState34(0);
|
|
6712
|
+
useEffect27(() => {
|
|
6544
6713
|
if (!token) return;
|
|
6545
6714
|
let cancelled = false;
|
|
6546
6715
|
client.billing.paymentMethods(token).then((result) => {
|
|
@@ -6556,7 +6725,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6556
6725
|
cancelled = true;
|
|
6557
6726
|
};
|
|
6558
6727
|
}, [client, token, version]);
|
|
6559
|
-
const wrap = (content) => /* @__PURE__ */
|
|
6728
|
+
const wrap = (content) => /* @__PURE__ */ jsx37("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
|
|
6560
6729
|
if (sessionLoading) return wrap("Loading\u2026");
|
|
6561
6730
|
if (!token) return wrap("Sign in to manage your payment method.");
|
|
6562
6731
|
switch (state.kind) {
|
|
@@ -6564,11 +6733,11 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6564
6733
|
return wrap("Loading\u2026");
|
|
6565
6734
|
case "error":
|
|
6566
6735
|
return wrap(
|
|
6567
|
-
/* @__PURE__ */
|
|
6736
|
+
/* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
|
|
6568
6737
|
);
|
|
6569
6738
|
case "managed":
|
|
6570
6739
|
return wrap(
|
|
6571
|
-
/* @__PURE__ */
|
|
6740
|
+
/* @__PURE__ */ jsx37("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
|
|
6572
6741
|
);
|
|
6573
6742
|
}
|
|
6574
6743
|
const card = state.cards.find((saved) => saved.isDefault) ?? null;
|
|
@@ -6588,7 +6757,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6588
6757
|
};
|
|
6589
6758
|
return wrap(
|
|
6590
6759
|
/* @__PURE__ */ jsxs35(Fragment12, { children: [
|
|
6591
|
-
/* @__PURE__ */
|
|
6760
|
+
/* @__PURE__ */ jsx37("div", { className: "b316-label", children: "Payment method" }),
|
|
6592
6761
|
card ? /* @__PURE__ */ jsxs35("div", { children: [
|
|
6593
6762
|
/* @__PURE__ */ jsxs35("div", { children: [
|
|
6594
6763
|
brandName(card.brand),
|
|
@@ -6601,9 +6770,9 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6601
6770
|
"/",
|
|
6602
6771
|
card.expYear
|
|
6603
6772
|
] }) : null
|
|
6604
|
-
] }) : /* @__PURE__ */
|
|
6773
|
+
] }) : /* @__PURE__ */ jsx37("p", { className: "b316-muted", children: "No card on file." }),
|
|
6605
6774
|
others.length > 0 ? /* @__PURE__ */ jsxs35("div", { style: { marginTop: 12 }, children: [
|
|
6606
|
-
/* @__PURE__ */
|
|
6775
|
+
/* @__PURE__ */ jsx37("div", { className: "b316-label", children: "Other saved cards" }),
|
|
6607
6776
|
others.map((saved) => /* @__PURE__ */ jsxs35("div", { className: "b316-row", style: { marginTop: 6 }, children: [
|
|
6608
6777
|
/* @__PURE__ */ jsxs35("span", { children: [
|
|
6609
6778
|
brandName(saved.brand),
|
|
@@ -6611,7 +6780,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6611
6780
|
saved.last4 ?? "????"
|
|
6612
6781
|
] }),
|
|
6613
6782
|
/* @__PURE__ */ jsxs35("span", { children: [
|
|
6614
|
-
/* @__PURE__ */
|
|
6783
|
+
/* @__PURE__ */ jsx37(
|
|
6615
6784
|
"button",
|
|
6616
6785
|
{
|
|
6617
6786
|
type: "button",
|
|
@@ -6625,7 +6794,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6625
6794
|
}
|
|
6626
6795
|
),
|
|
6627
6796
|
" ",
|
|
6628
|
-
/* @__PURE__ */
|
|
6797
|
+
/* @__PURE__ */ jsx37(
|
|
6629
6798
|
"button",
|
|
6630
6799
|
{
|
|
6631
6800
|
type: "button",
|
|
@@ -6641,8 +6810,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6641
6810
|
] })
|
|
6642
6811
|
] }, saved.id))
|
|
6643
6812
|
] }) : null,
|
|
6644
|
-
error ? /* @__PURE__ */
|
|
6645
|
-
/* @__PURE__ */
|
|
6813
|
+
error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6814
|
+
/* @__PURE__ */ jsx37(
|
|
6646
6815
|
"button",
|
|
6647
6816
|
{
|
|
6648
6817
|
type: "button",
|
|
@@ -6671,8 +6840,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6671
6840
|
}
|
|
6672
6841
|
|
|
6673
6842
|
// src/PlanChangeReview.tsx
|
|
6674
|
-
import { useCallback as
|
|
6675
|
-
import { Fragment as Fragment13, jsx as
|
|
6843
|
+
import { useCallback as useCallback12, useEffect as useEffect28, useState as useState35 } from "react";
|
|
6844
|
+
import { Fragment as Fragment13, jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
6676
6845
|
function money5(amount, currency) {
|
|
6677
6846
|
if (amount === null) return "\u2014";
|
|
6678
6847
|
const value = Number(amount);
|
|
@@ -6705,12 +6874,12 @@ function PlanChangeReview({
|
|
|
6705
6874
|
style
|
|
6706
6875
|
}) {
|
|
6707
6876
|
const { client, token } = useBase316();
|
|
6708
|
-
const [timing, setTiming] =
|
|
6709
|
-
const [preview, setPreview] =
|
|
6710
|
-
const [error, setError] =
|
|
6711
|
-
const [needsCard, setNeedsCard] =
|
|
6712
|
-
const [busy, setBusy] =
|
|
6713
|
-
|
|
6877
|
+
const [timing, setTiming] = useState35(void 0);
|
|
6878
|
+
const [preview, setPreview] = useState35(null);
|
|
6879
|
+
const [error, setError] = useState35(null);
|
|
6880
|
+
const [needsCard, setNeedsCard] = useState35(false);
|
|
6881
|
+
const [busy, setBusy] = useState35(false);
|
|
6882
|
+
useEffect28(() => {
|
|
6714
6883
|
if (!token) return;
|
|
6715
6884
|
let cancelled = false;
|
|
6716
6885
|
client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
|
|
@@ -6727,7 +6896,7 @@ function PlanChangeReview({
|
|
|
6727
6896
|
cancelled = true;
|
|
6728
6897
|
};
|
|
6729
6898
|
}, [client, token, planVersionId, timing]);
|
|
6730
|
-
const confirm =
|
|
6899
|
+
const confirm = useCallback12(async () => {
|
|
6731
6900
|
if (!token || !preview) return;
|
|
6732
6901
|
setBusy(true);
|
|
6733
6902
|
setError(null);
|
|
@@ -6748,7 +6917,7 @@ function PlanChangeReview({
|
|
|
6748
6917
|
setBusy(false);
|
|
6749
6918
|
}
|
|
6750
6919
|
}, [client, token, preview, planVersionId, onDone]);
|
|
6751
|
-
const addCard =
|
|
6920
|
+
const addCard = useCallback12(async () => {
|
|
6752
6921
|
if (onNeedsCard) {
|
|
6753
6922
|
onNeedsCard();
|
|
6754
6923
|
return;
|
|
@@ -6762,12 +6931,12 @@ function PlanChangeReview({
|
|
|
6762
6931
|
setError("Cards cannot be added here right now.");
|
|
6763
6932
|
}
|
|
6764
6933
|
}, [client, token, onNeedsCard]);
|
|
6765
|
-
const card = (content) => /* @__PURE__ */
|
|
6934
|
+
const card = (content) => /* @__PURE__ */ jsx38("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
|
|
6766
6935
|
if (error && !preview) {
|
|
6767
6936
|
return card(
|
|
6768
6937
|
/* @__PURE__ */ jsxs36(Fragment13, { children: [
|
|
6769
|
-
/* @__PURE__ */
|
|
6770
|
-
onCancel ? /* @__PURE__ */
|
|
6938
|
+
/* @__PURE__ */ jsx38("div", { className: "b316-error", role: "alert", children: error }),
|
|
6939
|
+
onCancel ? /* @__PURE__ */ jsx38("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
|
|
6771
6940
|
] })
|
|
6772
6941
|
);
|
|
6773
6942
|
}
|
|
@@ -6789,17 +6958,17 @@ function PlanChangeReview({
|
|
|
6789
6958
|
"From ",
|
|
6790
6959
|
from.planName
|
|
6791
6960
|
] }),
|
|
6792
|
-
error ? /* @__PURE__ */
|
|
6793
|
-
changes.length === 0 ? /* @__PURE__ */
|
|
6794
|
-
/* @__PURE__ */
|
|
6795
|
-
/* @__PURE__ */
|
|
6796
|
-
/* @__PURE__ */
|
|
6797
|
-
/* @__PURE__ */
|
|
6961
|
+
error ? /* @__PURE__ */ jsx38("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6962
|
+
changes.length === 0 ? /* @__PURE__ */ jsx38("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs36("table", { className: "b316-review-table", children: [
|
|
6963
|
+
/* @__PURE__ */ jsx38("thead", { children: /* @__PURE__ */ jsxs36("tr", { children: [
|
|
6964
|
+
/* @__PURE__ */ jsx38("th", { children: "Feature" }),
|
|
6965
|
+
/* @__PURE__ */ jsx38("th", { children: from.planName }),
|
|
6966
|
+
/* @__PURE__ */ jsx38("th", { children: to.planName })
|
|
6798
6967
|
] }) }),
|
|
6799
|
-
/* @__PURE__ */
|
|
6800
|
-
/* @__PURE__ */
|
|
6801
|
-
/* @__PURE__ */
|
|
6802
|
-
/* @__PURE__ */
|
|
6968
|
+
/* @__PURE__ */ jsx38("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs36("tr", { children: [
|
|
6969
|
+
/* @__PURE__ */ jsx38("td", { children: change.featureName }),
|
|
6970
|
+
/* @__PURE__ */ jsx38("td", { children: limitText(change.before, change.type) }),
|
|
6971
|
+
/* @__PURE__ */ jsx38(
|
|
6803
6972
|
"td",
|
|
6804
6973
|
{
|
|
6805
6974
|
className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
|
|
@@ -6824,8 +6993,8 @@ function PlanChangeReview({
|
|
|
6824
6993
|
] })
|
|
6825
6994
|
] }) : null,
|
|
6826
6995
|
Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
|
|
6827
|
-
/* @__PURE__ */
|
|
6828
|
-
/* @__PURE__ */
|
|
6996
|
+
/* @__PURE__ */ jsx38("span", { className: "b316-muted", children: "Usage so far this period" }),
|
|
6997
|
+
/* @__PURE__ */ jsx38("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
|
|
6829
6998
|
] }) : null,
|
|
6830
6999
|
/* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
|
|
6831
7000
|
/* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
|
|
@@ -6835,11 +7004,11 @@ function PlanChangeReview({
|
|
|
6835
7004
|
" \u2013 ",
|
|
6836
7005
|
day4(now.newPeriod.end)
|
|
6837
7006
|
] }),
|
|
6838
|
-
/* @__PURE__ */
|
|
7007
|
+
/* @__PURE__ */ jsx38("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
|
|
6839
7008
|
] }),
|
|
6840
7009
|
now.net !== null ? /* @__PURE__ */ jsxs36("div", { className: "b316-row b316-invoice-total", children: [
|
|
6841
|
-
/* @__PURE__ */
|
|
6842
|
-
/* @__PURE__ */
|
|
7010
|
+
/* @__PURE__ */ jsx38("span", { children: "Due now" }),
|
|
7011
|
+
/* @__PURE__ */ jsx38("span", { className: "b316-num", children: money5(now.net, to.currency) })
|
|
6843
7012
|
] }) : null
|
|
6844
7013
|
] }) : /* @__PURE__ */ jsxs36("p", { children: [
|
|
6845
7014
|
"You keep ",
|
|
@@ -6854,7 +7023,7 @@ function PlanChangeReview({
|
|
|
6854
7023
|
preview.atPeriodEnd.nextInvoice.currency
|
|
6855
7024
|
)}.` : ""
|
|
6856
7025
|
] }),
|
|
6857
|
-
otherOpen ? /* @__PURE__ */
|
|
7026
|
+
otherOpen ? /* @__PURE__ */ jsx38(
|
|
6858
7027
|
"button",
|
|
6859
7028
|
{
|
|
6860
7029
|
type: "button",
|
|
@@ -6865,12 +7034,12 @@ function PlanChangeReview({
|
|
|
6865
7034
|
},
|
|
6866
7035
|
children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
|
|
6867
7036
|
}
|
|
6868
|
-
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */
|
|
7037
|
+
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx38("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
|
|
6869
7038
|
needsCard ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", role: "status", children: [
|
|
6870
7039
|
"A card is needed for a change that is charged now.",
|
|
6871
|
-
/* @__PURE__ */
|
|
7040
|
+
/* @__PURE__ */ jsx38("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx38("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
|
|
6872
7041
|
] }) : /* @__PURE__ */ jsxs36("div", { className: "b316-review-actions", children: [
|
|
6873
|
-
/* @__PURE__ */
|
|
7042
|
+
/* @__PURE__ */ jsx38(
|
|
6874
7043
|
"button",
|
|
6875
7044
|
{
|
|
6876
7045
|
type: "button",
|
|
@@ -6890,7 +7059,7 @@ function PlanChangeReview({
|
|
|
6890
7059
|
}
|
|
6891
7060
|
|
|
6892
7061
|
// src/BillingPortal.tsx
|
|
6893
|
-
import { Fragment as Fragment14, jsx as
|
|
7062
|
+
import { Fragment as Fragment14, jsx as jsx39, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
6894
7063
|
function BillingPortal({
|
|
6895
7064
|
returnUrl,
|
|
6896
7065
|
featuredPlanKey,
|
|
@@ -6900,12 +7069,12 @@ function BillingPortal({
|
|
|
6900
7069
|
style
|
|
6901
7070
|
}) {
|
|
6902
7071
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6903
|
-
const [overview, setOverview] =
|
|
6904
|
-
const [failed, setFailed] =
|
|
6905
|
-
const [version, setVersion] =
|
|
6906
|
-
const [reviewing, setReviewing] =
|
|
6907
|
-
const [notice, setNotice] =
|
|
6908
|
-
|
|
7072
|
+
const [overview, setOverview] = useState36(null);
|
|
7073
|
+
const [failed, setFailed] = useState36(false);
|
|
7074
|
+
const [version, setVersion] = useState36(0);
|
|
7075
|
+
const [reviewing, setReviewing] = useState36(null);
|
|
7076
|
+
const [notice, setNotice] = useState36(null);
|
|
7077
|
+
useEffect29(() => {
|
|
6909
7078
|
if (!token) return;
|
|
6910
7079
|
let cancelled = false;
|
|
6911
7080
|
client.billing.subscription(token).then((result) => {
|
|
@@ -6924,28 +7093,28 @@ function BillingPortal({
|
|
|
6924
7093
|
cancelled = true;
|
|
6925
7094
|
};
|
|
6926
7095
|
}, [client, token, version]);
|
|
6927
|
-
const refresh =
|
|
7096
|
+
const refresh = useCallback13(() => {
|
|
6928
7097
|
setNotice(null);
|
|
6929
7098
|
setVersion((value) => value + 1);
|
|
6930
7099
|
}, []);
|
|
6931
|
-
const shell = (content) => /* @__PURE__ */
|
|
6932
|
-
if (sessionLoading) return shell(/* @__PURE__ */
|
|
6933
|
-
if (!token) return shell(/* @__PURE__ */
|
|
7100
|
+
const shell = (content) => /* @__PURE__ */ jsx39("div", { className: cls("b316-billing-portal", className), style, children: content });
|
|
7101
|
+
if (sessionLoading) return shell(/* @__PURE__ */ jsx39("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
7102
|
+
if (!token) return shell(/* @__PURE__ */ jsx39("div", { className: "b316-card", children: "Sign in to manage your billing." }));
|
|
6934
7103
|
if (failed) {
|
|
6935
7104
|
return shell(
|
|
6936
|
-
/* @__PURE__ */
|
|
7105
|
+
/* @__PURE__ */ jsx39("div", { className: "b316-card", children: /* @__PURE__ */ jsx39("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
|
|
6937
7106
|
);
|
|
6938
7107
|
}
|
|
6939
|
-
if (!overview) return shell(/* @__PURE__ */
|
|
7108
|
+
if (!overview) return shell(/* @__PURE__ */ jsx39("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6940
7109
|
const { subscription, managedBy, quantityPriced } = overview;
|
|
6941
7110
|
const canChange = Boolean(subscription) && !managedBy;
|
|
6942
7111
|
return shell(
|
|
6943
7112
|
/* @__PURE__ */ jsxs37(Fragment14, { children: [
|
|
6944
|
-
notice ? /* @__PURE__ */
|
|
6945
|
-
/* @__PURE__ */
|
|
6946
|
-
canChange ? /* @__PURE__ */
|
|
6947
|
-
canChange && quantityPriced ? /* @__PURE__ */
|
|
6948
|
-
reviewing ? /* @__PURE__ */
|
|
7113
|
+
notice ? /* @__PURE__ */ jsx39("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
|
|
7114
|
+
/* @__PURE__ */ jsx39(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
|
|
7115
|
+
canChange ? /* @__PURE__ */ jsx39(UpcomingInvoice, {}, `next-${version}`) : null,
|
|
7116
|
+
canChange && quantityPriced ? /* @__PURE__ */ jsx39(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
|
|
7117
|
+
reviewing ? /* @__PURE__ */ jsx39(
|
|
6949
7118
|
PlanChangeReview,
|
|
6950
7119
|
{
|
|
6951
7120
|
planVersionId: reviewing,
|
|
@@ -6959,8 +7128,8 @@ function BillingPortal({
|
|
|
6959
7128
|
}
|
|
6960
7129
|
}
|
|
6961
7130
|
) : /* @__PURE__ */ jsxs37("section", { children: [
|
|
6962
|
-
/* @__PURE__ */
|
|
6963
|
-
/* @__PURE__ */
|
|
7131
|
+
/* @__PURE__ */ jsx39("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
|
|
7132
|
+
/* @__PURE__ */ jsx39(
|
|
6964
7133
|
PricingTable,
|
|
6965
7134
|
{
|
|
6966
7135
|
featuredPlanKey,
|
|
@@ -6972,17 +7141,17 @@ function BillingPortal({
|
|
|
6972
7141
|
`plans-${version}`
|
|
6973
7142
|
)
|
|
6974
7143
|
] }),
|
|
6975
|
-
/* @__PURE__ */
|
|
6976
|
-
managedBy ? null : /* @__PURE__ */
|
|
6977
|
-
/* @__PURE__ */
|
|
6978
|
-
billingDetails === void 0 ? /* @__PURE__ */
|
|
7144
|
+
/* @__PURE__ */ jsx39(CreditBalances, {}, `credits-${version}`),
|
|
7145
|
+
managedBy ? null : /* @__PURE__ */ jsx39(PaymentMethod, { returnUrl }, `card-${version}`),
|
|
7146
|
+
/* @__PURE__ */ jsx39(Invoices, {}, `invoices-${version}`),
|
|
7147
|
+
billingDetails === void 0 ? /* @__PURE__ */ jsx39(BillingDetailsForm, {}, `details-${version}`) : billingDetails
|
|
6979
7148
|
] })
|
|
6980
7149
|
);
|
|
6981
7150
|
}
|
|
6982
7151
|
|
|
6983
7152
|
// src/ApiKeyManager.tsx
|
|
6984
|
-
import { useCallback as
|
|
6985
|
-
import { jsx as
|
|
7153
|
+
import { useCallback as useCallback14, useEffect as useEffect30, useState as useState37 } from "react";
|
|
7154
|
+
import { jsx as jsx40, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
6986
7155
|
function duration(seconds) {
|
|
6987
7156
|
if (seconds % 3600 === 0) {
|
|
6988
7157
|
return `${seconds / 3600}h`;
|
|
@@ -6999,17 +7168,17 @@ function ApiKeyManager({
|
|
|
6999
7168
|
audience
|
|
7000
7169
|
}) {
|
|
7001
7170
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
7002
|
-
const [resources, setResources] =
|
|
7003
|
-
const [credentials, setCredentials] =
|
|
7004
|
-
const [
|
|
7005
|
-
const [busy, setBusy] =
|
|
7006
|
-
const [error, setError] =
|
|
7007
|
-
const [creating, setCreating] =
|
|
7008
|
-
const [name, setName] =
|
|
7009
|
-
const [chosen, setChosen] =
|
|
7010
|
-
const [resourceId, setResourceId] =
|
|
7011
|
-
const [issued, setIssued] =
|
|
7012
|
-
const load =
|
|
7171
|
+
const [resources, setResources] = useState37([]);
|
|
7172
|
+
const [credentials, setCredentials] = useState37([]);
|
|
7173
|
+
const [loading2, setLoading] = useState37(true);
|
|
7174
|
+
const [busy, setBusy] = useState37(false);
|
|
7175
|
+
const [error, setError] = useState37(null);
|
|
7176
|
+
const [creating, setCreating] = useState37(false);
|
|
7177
|
+
const [name, setName] = useState37("");
|
|
7178
|
+
const [chosen, setChosen] = useState37([]);
|
|
7179
|
+
const [resourceId, setResourceId] = useState37(null);
|
|
7180
|
+
const [issued, setIssued] = useState37(null);
|
|
7181
|
+
const load = useCallback14(async () => {
|
|
7013
7182
|
if (!token) {
|
|
7014
7183
|
setLoading(false);
|
|
7015
7184
|
return;
|
|
@@ -7030,20 +7199,20 @@ function ApiKeyManager({
|
|
|
7030
7199
|
setLoading(false);
|
|
7031
7200
|
}
|
|
7032
7201
|
}, [client, token, audience]);
|
|
7033
|
-
|
|
7202
|
+
useEffect30(() => {
|
|
7034
7203
|
void load();
|
|
7035
7204
|
}, [load]);
|
|
7036
|
-
if (sessionLoading ||
|
|
7037
|
-
return /* @__PURE__ */
|
|
7205
|
+
if (sessionLoading || loading2) {
|
|
7206
|
+
return /* @__PURE__ */ jsx40("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
7038
7207
|
}
|
|
7039
7208
|
if (!token) {
|
|
7040
|
-
return /* @__PURE__ */
|
|
7209
|
+
return /* @__PURE__ */ jsx40("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
|
|
7041
7210
|
}
|
|
7042
7211
|
if (error) {
|
|
7043
|
-
return /* @__PURE__ */
|
|
7212
|
+
return /* @__PURE__ */ jsx40("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx40("div", { className: "b316-error", role: "alert", children: error }) });
|
|
7044
7213
|
}
|
|
7045
7214
|
if (resources.length === 0) {
|
|
7046
|
-
return /* @__PURE__ */
|
|
7215
|
+
return /* @__PURE__ */ jsx40("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
|
|
7047
7216
|
}
|
|
7048
7217
|
const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
|
|
7049
7218
|
const reset = () => {
|
|
@@ -7053,36 +7222,36 @@ function ApiKeyManager({
|
|
|
7053
7222
|
setIssued(null);
|
|
7054
7223
|
};
|
|
7055
7224
|
return /* @__PURE__ */ jsxs38("div", { className: cls("b316-card", className), style, children: [
|
|
7056
|
-
error ? /* @__PURE__ */
|
|
7057
|
-
resources.length > 1 ? /* @__PURE__ */
|
|
7225
|
+
error ? /* @__PURE__ */ jsx40("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
7226
|
+
resources.length > 1 ? /* @__PURE__ */ jsx40(
|
|
7058
7227
|
"select",
|
|
7059
7228
|
{
|
|
7060
7229
|
className: "b316-input",
|
|
7061
7230
|
value: resource.id,
|
|
7062
7231
|
onChange: (event) => setResourceId(event.target.value),
|
|
7063
7232
|
style: { marginBottom: 14 },
|
|
7064
|
-
children: resources.map((item) => /* @__PURE__ */
|
|
7233
|
+
children: resources.map((item) => /* @__PURE__ */ jsx40("option", { value: item.id, children: item.name }, item.id))
|
|
7065
7234
|
}
|
|
7066
|
-
) : /* @__PURE__ */
|
|
7235
|
+
) : /* @__PURE__ */ jsx40("div", { className: "b316-plan-name", children: resource.name }),
|
|
7067
7236
|
resource.rateLimit ? /* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
|
|
7068
7237
|
resource.rateLimit.requestsPerWindow,
|
|
7069
7238
|
" requests per",
|
|
7070
7239
|
" ",
|
|
7071
7240
|
duration(resource.rateLimit.windowSeconds),
|
|
7072
7241
|
resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
|
|
7073
|
-
] }) : /* @__PURE__ */
|
|
7074
|
-
credentials.length === 0 ? /* @__PURE__ */
|
|
7242
|
+
] }) : /* @__PURE__ */ jsx40("div", { className: "b316-muted", children: "No rate limit." }),
|
|
7243
|
+
credentials.length === 0 ? /* @__PURE__ */ jsx40("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx40("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs38("li", { className: "b316-list-item", children: [
|
|
7075
7244
|
/* @__PURE__ */ jsxs38("div", { children: [
|
|
7076
|
-
/* @__PURE__ */
|
|
7245
|
+
/* @__PURE__ */ jsx40("div", { className: "b316-plan-name", children: credential.name }),
|
|
7077
7246
|
/* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
|
|
7078
|
-
/* @__PURE__ */
|
|
7247
|
+
/* @__PURE__ */ jsx40("code", { children: credential.clientId }),
|
|
7079
7248
|
credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
|
|
7080
7249
|
credential.disabled ? " \xB7 Disabled" : null
|
|
7081
7250
|
] }),
|
|
7082
|
-
/* @__PURE__ */
|
|
7251
|
+
/* @__PURE__ */ jsx40("div", { className: "b316-muted", children: credential.scopes.join(", ") })
|
|
7083
7252
|
] }),
|
|
7084
7253
|
/* @__PURE__ */ jsxs38("div", { style: { display: "flex", gap: 8 }, children: [
|
|
7085
|
-
/* @__PURE__ */
|
|
7254
|
+
/* @__PURE__ */ jsx40(
|
|
7086
7255
|
"button",
|
|
7087
7256
|
{
|
|
7088
7257
|
type: "button",
|
|
@@ -7111,7 +7280,7 @@ function ApiKeyManager({
|
|
|
7111
7280
|
children: "Rotate"
|
|
7112
7281
|
}
|
|
7113
7282
|
),
|
|
7114
|
-
/* @__PURE__ */
|
|
7283
|
+
/* @__PURE__ */ jsx40(
|
|
7115
7284
|
ConfirmButton,
|
|
7116
7285
|
{
|
|
7117
7286
|
className: "b316-button b316-button-secondary",
|
|
@@ -7136,10 +7305,10 @@ function ApiKeyManager({
|
|
|
7136
7305
|
] })
|
|
7137
7306
|
] }, credential.clientId)) }),
|
|
7138
7307
|
issued ? /* @__PURE__ */ jsxs38("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
|
|
7139
|
-
/* @__PURE__ */
|
|
7308
|
+
/* @__PURE__ */ jsx40("strong", { children: "Copy this now." }),
|
|
7140
7309
|
" It is shown once and cannot be retrieved again.",
|
|
7141
|
-
/* @__PURE__ */
|
|
7142
|
-
/* @__PURE__ */
|
|
7310
|
+
/* @__PURE__ */ jsx40("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx40("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
|
|
7311
|
+
/* @__PURE__ */ jsx40(
|
|
7143
7312
|
"button",
|
|
7144
7313
|
{
|
|
7145
7314
|
type: "button",
|
|
@@ -7152,7 +7321,7 @@ function ApiKeyManager({
|
|
|
7152
7321
|
children: "Copy"
|
|
7153
7322
|
}
|
|
7154
7323
|
),
|
|
7155
|
-
/* @__PURE__ */
|
|
7324
|
+
/* @__PURE__ */ jsx40(
|
|
7156
7325
|
"button",
|
|
7157
7326
|
{
|
|
7158
7327
|
type: "button",
|
|
@@ -7164,7 +7333,7 @@ function ApiKeyManager({
|
|
|
7164
7333
|
)
|
|
7165
7334
|
] }) : null,
|
|
7166
7335
|
creating && !issued ? /* @__PURE__ */ jsxs38("div", { style: { marginTop: 14 }, children: [
|
|
7167
|
-
/* @__PURE__ */
|
|
7336
|
+
/* @__PURE__ */ jsx40(
|
|
7168
7337
|
"input",
|
|
7169
7338
|
{
|
|
7170
7339
|
className: "b316-input",
|
|
@@ -7175,7 +7344,7 @@ function ApiKeyManager({
|
|
|
7175
7344
|
),
|
|
7176
7345
|
/* @__PURE__ */ jsxs38("div", { style: { marginTop: 10 }, children: [
|
|
7177
7346
|
resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox", children: [
|
|
7178
|
-
/* @__PURE__ */
|
|
7347
|
+
/* @__PURE__ */ jsx40(
|
|
7179
7348
|
"input",
|
|
7180
7349
|
{
|
|
7181
7350
|
type: "checkbox",
|
|
@@ -7185,19 +7354,19 @@ function ApiKeyManager({
|
|
|
7185
7354
|
)
|
|
7186
7355
|
}
|
|
7187
7356
|
),
|
|
7188
|
-
/* @__PURE__ */
|
|
7357
|
+
/* @__PURE__ */ jsx40("code", { children: scope.key }),
|
|
7189
7358
|
scope.description ? /* @__PURE__ */ jsxs38("span", { className: "b316-muted", children: [
|
|
7190
7359
|
" \u2014 ",
|
|
7191
7360
|
scope.description
|
|
7192
7361
|
] }) : null
|
|
7193
7362
|
] }, scope.key)),
|
|
7194
7363
|
resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox b316-muted", children: [
|
|
7195
|
-
/* @__PURE__ */
|
|
7196
|
-
/* @__PURE__ */
|
|
7197
|
-
/* @__PURE__ */
|
|
7364
|
+
/* @__PURE__ */ jsx40("input", { type: "checkbox", disabled: true }),
|
|
7365
|
+
/* @__PURE__ */ jsx40("code", { children: scope.key }),
|
|
7366
|
+
/* @__PURE__ */ jsx40("span", { children: " \u2014 not included in your plan" })
|
|
7198
7367
|
] }, scope.key))
|
|
7199
7368
|
] }),
|
|
7200
|
-
/* @__PURE__ */
|
|
7369
|
+
/* @__PURE__ */ jsx40(
|
|
7201
7370
|
"button",
|
|
7202
7371
|
{
|
|
7203
7372
|
type: "button",
|
|
@@ -7231,7 +7400,7 @@ function ApiKeyManager({
|
|
|
7231
7400
|
children: "Create key"
|
|
7232
7401
|
}
|
|
7233
7402
|
),
|
|
7234
|
-
/* @__PURE__ */
|
|
7403
|
+
/* @__PURE__ */ jsx40(
|
|
7235
7404
|
"button",
|
|
7236
7405
|
{
|
|
7237
7406
|
type: "button",
|
|
@@ -7242,7 +7411,7 @@ function ApiKeyManager({
|
|
|
7242
7411
|
}
|
|
7243
7412
|
)
|
|
7244
7413
|
] }) : null,
|
|
7245
|
-
!creating && !issued ? /* @__PURE__ */
|
|
7414
|
+
!creating && !issued ? /* @__PURE__ */ jsx40(
|
|
7246
7415
|
"button",
|
|
7247
7416
|
{
|
|
7248
7417
|
type: "button",
|
|
@@ -7284,12 +7453,12 @@ var MANIFEST = [
|
|
|
7284
7453
|
},
|
|
7285
7454
|
{
|
|
7286
7455
|
name: "appearance",
|
|
7287
|
-
summary: "
|
|
7456
|
+
summary: "Colors, radius and font as tokens. Restyles everything at once.",
|
|
7288
7457
|
required: false
|
|
7289
7458
|
},
|
|
7290
7459
|
{
|
|
7291
7460
|
name: "tenant",
|
|
7292
|
-
summary: "White-label everything inside for one tenant \u2014 `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and
|
|
7461
|
+
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.",
|
|
7293
7462
|
required: false
|
|
7294
7463
|
},
|
|
7295
7464
|
...appearance
|
|
@@ -7358,7 +7527,7 @@ var MANIFEST = [
|
|
|
7358
7527
|
{ name: "labels", summary: "Wording for the form, for translation.", required: false },
|
|
7359
7528
|
{
|
|
7360
7529
|
name: "secondFactorLabels",
|
|
7361
|
-
summary: "Wording for the second-factor step (code box, or
|
|
7530
|
+
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.",
|
|
7362
7531
|
required: false
|
|
7363
7532
|
},
|
|
7364
7533
|
...appearance
|
|
@@ -7733,10 +7902,20 @@ var MANIFEST = [
|
|
|
7733
7902
|
props: [],
|
|
7734
7903
|
seeAlso: ["PricingTable"]
|
|
7735
7904
|
},
|
|
7905
|
+
{
|
|
7906
|
+
name: "useAddons",
|
|
7907
|
+
kind: "hook",
|
|
7908
|
+
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.",
|
|
7909
|
+
useWhen: "You sell extras on top of a plan (more apps, seats, storage) as self-serve addons.",
|
|
7910
|
+
requires: ["session"],
|
|
7911
|
+
props: [],
|
|
7912
|
+
whenUnmet: "Loads nothing without a session; `lastError` carries the API's code.",
|
|
7913
|
+
seeAlso: ["usePlans", "SubscriptionManager"]
|
|
7914
|
+
},
|
|
7736
7915
|
{
|
|
7737
7916
|
name: "SubscriptionManager",
|
|
7738
7917
|
kind: "component",
|
|
7739
|
-
summary: "The current plan, its renewal date, a scheduled plan change with its undo,
|
|
7918
|
+
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.",
|
|
7740
7919
|
useWhen: "A billing settings page.",
|
|
7741
7920
|
requires: ["session"],
|
|
7742
7921
|
props: [
|
|
@@ -8017,7 +8196,7 @@ var MANIFEST = [
|
|
|
8017
8196
|
{
|
|
8018
8197
|
name: "Chart",
|
|
8019
8198
|
kind: "component",
|
|
8020
|
-
summary: "Records over time, counted or
|
|
8199
|
+
summary: "Records over time, counted or totaled.",
|
|
8021
8200
|
useWhen: "The question is how many or how much, by day, week or month.",
|
|
8022
8201
|
requires: ["session", "collection"],
|
|
8023
8202
|
bindsToCollection: true,
|
|
@@ -8220,6 +8399,7 @@ export {
|
|
|
8220
8399
|
VerifyEmail,
|
|
8221
8400
|
componentsRequiring,
|
|
8222
8401
|
describeComponent,
|
|
8402
|
+
useAddons,
|
|
8223
8403
|
useBase316,
|
|
8224
8404
|
useCollection,
|
|
8225
8405
|
usePaymentLink,
|