@base316/react 0.5.2 → 0.7.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 +49 -0
- package/dist/index.cjs +1392 -975
- 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 +1333 -914
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +97 -4
- package/dist/src/SignIn.d.ts +78 -17
- package/dist/src/SignIn.d.ts.map +1 -1
- package/dist/src/SignUp.d.ts +25 -1
- package/dist/src/SignUp.d.ts.map +1 -1
- package/dist/src/SocialButtons.d.ts +16 -0
- package/dist/src/SocialButtons.d.ts.map +1 -0
- package/dist/src/SocialSignIn.d.ts +32 -0
- package/dist/src/SocialSignIn.d.ts.map +1 -0
- package/dist/src/appearance.d.ts +1 -1
- package/dist/src/appearance.d.ts.map +1 -1
- package/dist/src/manifest.d.ts.map +1 -1
- package/dist/src/provider.d.ts +9 -1
- package/dist/src/provider.d.ts.map +1 -1
- package/dist/src/sign-in-methods.d.ts +66 -0
- package/dist/src/sign-in-methods.d.ts.map +1 -0
- package/dist/src/social-icons.d.ts +11 -0
- package/dist/src/social-icons.d.ts.map +1 -0
- package/dist/src/test/harness.d.ts +2 -1
- package/dist/src/test/harness.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,7 @@ __export(index_exports, {
|
|
|
63
63
|
SecondFactorStep: () => SecondFactorStep,
|
|
64
64
|
SignIn: () => SignIn,
|
|
65
65
|
SignUp: () => SignUp,
|
|
66
|
+
SocialSignIn: () => SocialSignIn,
|
|
66
67
|
SubscriptionManager: () => SubscriptionManager,
|
|
67
68
|
TeamMembers: () => TeamMembers,
|
|
68
69
|
TwoFactorManager: () => TwoFactorManager,
|
|
@@ -397,6 +398,23 @@ var STYLESHEET_EXTRA = `
|
|
|
397
398
|
border-bottom: 2px solid transparent; margin-bottom: -1px;
|
|
398
399
|
}
|
|
399
400
|
.b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }
|
|
401
|
+
.b316-social { display: flex; flex-direction: column; gap: 8px; }
|
|
402
|
+
.b316-social-button {
|
|
403
|
+
display: flex; align-items: center; justify-content: center; gap: 10px;
|
|
404
|
+
width: 100%; min-height: 40px; padding: 9px 14px;
|
|
405
|
+
border: 1px solid; border-radius: calc(var(--b316-radius) / 1.6);
|
|
406
|
+
font: inherit; font-weight: 500; cursor: pointer;
|
|
407
|
+
}
|
|
408
|
+
.b316-social-button:hover:not([disabled]) { filter: brightness(.96); }
|
|
409
|
+
.b316-social-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }
|
|
410
|
+
.b316-social-button[disabled] { opacity: .55; cursor: not-allowed; }
|
|
411
|
+
.b316-social-icon { display: inline-flex; width: 18px; height: 18px; flex: none; }
|
|
412
|
+
.b316-social-icon svg { width: 18px; height: 18px; }
|
|
413
|
+
.b316-divider {
|
|
414
|
+
display: flex; align-items: center; gap: 10px; margin: 14px 0;
|
|
415
|
+
color: var(--b316-color-muted); font-size: .87em;
|
|
416
|
+
}
|
|
417
|
+
.b316-divider::before, .b316-divider::after { content: ""; flex: 1; border-top: 1px solid var(--b316-color-border); }
|
|
400
418
|
.b316-branding { display: flex; flex-direction: column; gap: 4px; }
|
|
401
419
|
.b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }
|
|
402
420
|
.b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }
|
|
@@ -714,12 +732,13 @@ function Base316Provider({
|
|
|
714
732
|
onTokenChange,
|
|
715
733
|
appearance: appearance2,
|
|
716
734
|
tenant,
|
|
735
|
+
organizationId,
|
|
717
736
|
className,
|
|
718
737
|
children
|
|
719
738
|
}) {
|
|
720
739
|
const client = (0, import_react.useMemo)(
|
|
721
|
-
() => new import_sdk.Base316Browser({ publishableKey, baseUrl }),
|
|
722
|
-
[publishableKey, baseUrl]
|
|
740
|
+
() => new import_sdk.Base316Browser({ publishableKey, baseUrl, organizationId: organizationId ?? void 0 }),
|
|
741
|
+
[publishableKey, baseUrl, organizationId]
|
|
723
742
|
);
|
|
724
743
|
(0, import_react.useEffect)(() => {
|
|
725
744
|
if (document.getElementById(STYLE_ELEMENT_ID)) {
|
|
@@ -1672,8 +1691,8 @@ function BillingDetailsForm({
|
|
|
1672
1691
|
}
|
|
1673
1692
|
|
|
1674
1693
|
// src/SignIn.tsx
|
|
1675
|
-
var
|
|
1676
|
-
var
|
|
1694
|
+
var import_sdk4 = require("@base316/sdk");
|
|
1695
|
+
var import_react8 = require("react");
|
|
1677
1696
|
|
|
1678
1697
|
// src/SecondFactorStep.tsx
|
|
1679
1698
|
var import_sdk2 = require("@base316/sdk");
|
|
@@ -2062,33 +2081,230 @@ function SecondFactorStep({
|
|
|
2062
2081
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cls("b316-mfa", className), style, children: body });
|
|
2063
2082
|
}
|
|
2064
2083
|
|
|
2065
|
-
// src/
|
|
2084
|
+
// src/sign-in-methods.ts
|
|
2085
|
+
var import_sdk3 = require("@base316/sdk");
|
|
2086
|
+
var import_react7 = require("react");
|
|
2087
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
2088
|
+
function loadSignInMethods(client) {
|
|
2089
|
+
let pending = cache.get(client);
|
|
2090
|
+
if (!pending) {
|
|
2091
|
+
pending = client.auth.methods();
|
|
2092
|
+
cache.set(client, pending);
|
|
2093
|
+
pending.catch(() => cache.delete(client));
|
|
2094
|
+
}
|
|
2095
|
+
return pending;
|
|
2096
|
+
}
|
|
2097
|
+
function useSignInMethods(client) {
|
|
2098
|
+
const [state, setState] = (0, import_react7.useState)({ status: "loading", methods: null });
|
|
2099
|
+
(0, import_react7.useEffect)(() => {
|
|
2100
|
+
let cancelled = false;
|
|
2101
|
+
loadSignInMethods(client).then((methods) => {
|
|
2102
|
+
if (!cancelled) setState({ status: "ready", methods });
|
|
2103
|
+
}).catch(() => {
|
|
2104
|
+
if (!cancelled) setState({ status: "unavailable", methods: null });
|
|
2105
|
+
});
|
|
2106
|
+
return () => {
|
|
2107
|
+
cancelled = true;
|
|
2108
|
+
};
|
|
2109
|
+
}, [client]);
|
|
2110
|
+
return state;
|
|
2111
|
+
}
|
|
2112
|
+
function resolveMethods(methods, props, currentPage) {
|
|
2113
|
+
if (!methods) {
|
|
2114
|
+
return {
|
|
2115
|
+
password: props.password !== false,
|
|
2116
|
+
passkeys: props.passkeys !== false,
|
|
2117
|
+
magicLink: props.magicLink !== false ? props.magicLinkRedirectUrl ?? null : null,
|
|
2118
|
+
phone: props.phone === true,
|
|
2119
|
+
social: [],
|
|
2120
|
+
sso: false,
|
|
2121
|
+
signUp: true,
|
|
2122
|
+
hostedUrl: void 0
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
const redirect = props.socialRedirectUrl;
|
|
2126
|
+
const only = Array.isArray(props.social) ? new Set(props.social.map((entry) => entry.toLowerCase())) : null;
|
|
2127
|
+
return {
|
|
2128
|
+
password: methods.password && props.password !== false,
|
|
2129
|
+
passkeys: methods.passkeys && props.passkeys !== false,
|
|
2130
|
+
magicLink: methods.magicLink && props.magicLink !== false ? props.magicLinkRedirectUrl ?? currentPage : null,
|
|
2131
|
+
phone: methods.phone && props.phone !== false,
|
|
2132
|
+
social: redirect && props.social !== false ? methods.social.filter(
|
|
2133
|
+
(option) => !only || only.has(option.slug.toLowerCase()) || only.has(option.provider.toLowerCase())
|
|
2134
|
+
) : [],
|
|
2135
|
+
sso: Boolean(redirect) && methods.sso && props.sso !== false,
|
|
2136
|
+
signUp: methods.signUp,
|
|
2137
|
+
hostedUrl: methods.hostedUrl
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
function beginRedirect(build, appState) {
|
|
2141
|
+
const { state, nonce } = (0, import_sdk3.createOAuthState)(appState);
|
|
2142
|
+
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
2143
|
+
document.cookie = `${import_sdk3.OAUTH_STATE_COOKIE}=${nonce}; Path=/; Max-Age=600; SameSite=Lax${secure}`;
|
|
2144
|
+
window.location.assign(build(state));
|
|
2145
|
+
}
|
|
2146
|
+
function currentPageUrl() {
|
|
2147
|
+
if (typeof window === "undefined") {
|
|
2148
|
+
return null;
|
|
2149
|
+
}
|
|
2150
|
+
return `${window.location.origin}${window.location.pathname}`;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
// src/social-icons.ts
|
|
2154
|
+
var PROVIDER_ICON = {
|
|
2155
|
+
GOOGLE: `<svg viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33Z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"/></svg>`,
|
|
2156
|
+
FACEBOOK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M24 12.07C24 5.4 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.05V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.68.24 2.68.24v2.96h-1.51c-1.49 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.61 23.1 24 18.1 24 12.07Z"/></svg>`,
|
|
2157
|
+
APPLE: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.05 12.54c-.03-2.74 2.24-4.06 2.34-4.12-1.28-1.86-3.26-2.12-3.96-2.15-1.69-.17-3.29 1-4.14 1-.85 0-2.17-.98-3.57-.95-1.83.03-3.53 1.07-4.47 2.71-1.91 3.31-.49 8.2 1.37 10.88.91 1.31 1.99 2.78 3.42 2.73 1.37-.06 1.89-.89 3.55-.89 1.66 0 2.13.89 3.58.86 1.48-.03 2.41-1.34 3.31-2.65 1.04-1.52 1.47-2.99 1.5-3.07-.03-.01-2.88-1.1-2.91-4.37ZM14.3 4.44c.75-.92 1.26-2.19 1.12-3.44-1.08.04-2.4.72-3.18 1.63-.7.81-1.31 2.11-1.15 3.35 1.21.09 2.45-.61 3.21-1.54Z"/></svg>`,
|
|
2158
|
+
MICROSOFT: `<svg viewBox="0 0 23 23" aria-hidden="true"><path fill="#f25022" d="M1 1h10v10H1z"/><path fill="#7fba00" d="M12 1h10v10H12z"/><path fill="#00a4ef" d="M1 12h10v10H1z"/><path fill="#ffb900" d="M12 12h10v10H12z"/></svg>`,
|
|
2159
|
+
GITHUB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.8 1.3 3.5 1 0-.8.4-1.3.7-1.6-2.7-.3-5.5-1.3-5.5-5.9 0-1.3.5-2.4 1.2-3.2 0-.4-.5-1.6.2-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0C17.4 4.6 18.4 5 18.4 5c.7 1.6.2 2.8.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.5.4.9 1.1.9 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .3Z"/></svg>`,
|
|
2160
|
+
GITLAB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e24329" d="m12 22.5-3.7-11.3h7.4L12 22.5Z"/><path fill="#fc6d26" d="M12 22.5 8.3 11.2H3.1L12 22.5Z"/><path fill="#fca326" d="M3.1 11.2 2 14.7a.8.8 0 0 0 .3.8l9.7 7-8.9-11.3Z"/><path fill="#e24329" d="M3.1 11.2h5.2L6.1 4.3a.4.4 0 0 0-.8 0l-2.2 6.9Z"/><path fill="#fc6d26" d="M12 22.5l3.7-11.3h5.2L12 22.5Z"/><path fill="#fca326" d="m20.9 11.2 1.1 3.5a.8.8 0 0 1-.3.8l-9.7 7 8.9-11.3Z"/><path fill="#e24329" d="M20.9 11.2h-5.2l2.2-6.9a.4.4 0 0 1 .8 0l2.2 6.9Z"/></svg>`,
|
|
2161
|
+
LINKEDIN: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05a3.74 3.74 0 0 1 3.37-1.85c3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13Zm1.78 13.02H3.55V9h3.57v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0Z"/></svg>`,
|
|
2162
|
+
// The four below are the Simple Icons marks (CC0), https://simpleicons.org.
|
|
2163
|
+
DISCORD: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg>`,
|
|
2164
|
+
TWITTER: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg>`,
|
|
2165
|
+
TWITCH: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>`,
|
|
2166
|
+
ROBLOX: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.926 23.998 0 18.892 5.075.002 24 5.108ZM15.348 10.09l-5.282-1.453-1.414 5.273 5.282 1.453z"/></svg>`,
|
|
2167
|
+
SLACK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e01e5a" d="M5.04 15.17a2.53 2.53 0 1 1-2.52-2.53h2.52v2.53Zm1.27 0a2.53 2.53 0 1 1 5.05 0v6.31a2.53 2.53 0 1 1-5.05 0v-6.31Z"/><path fill="#36c5f0" d="M8.83 5.04a2.53 2.53 0 1 1 2.53-2.52v2.52H8.83Zm0 1.28a2.53 2.53 0 1 1 0 5.05H2.52a2.53 2.53 0 1 1 0-5.05h6.31Z"/><path fill="#2eb67d" d="M18.96 8.83a2.53 2.53 0 1 1 2.52 2.53h-2.52V8.83Zm-1.27 0a2.53 2.53 0 1 1-5.05 0V2.52a2.53 2.53 0 1 1 5.05 0v6.31Z"/><path fill="#ecb22e" d="M15.17 18.96a2.53 2.53 0 1 1-2.53 2.52v-2.52h2.53Zm0-1.27a2.53 2.53 0 1 1 0-5.05h6.31a2.53 2.53 0 1 1 0 5.05h-6.31Z"/></svg>`
|
|
2168
|
+
};
|
|
2169
|
+
|
|
2170
|
+
// src/SocialButtons.tsx
|
|
2066
2171
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2172
|
+
function SocialButtons({
|
|
2173
|
+
options,
|
|
2174
|
+
continueWith,
|
|
2175
|
+
disabled,
|
|
2176
|
+
onChoose
|
|
2177
|
+
}) {
|
|
2178
|
+
if (options.length === 0) {
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|
|
2181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-social", children: options.map((option) => {
|
|
2182
|
+
const icon = PROVIDER_ICON[option.provider];
|
|
2183
|
+
const light = /^#f{3}(f{3})?$/i.test(option.buttonColor);
|
|
2184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2185
|
+
"button",
|
|
2186
|
+
{
|
|
2187
|
+
type: "button",
|
|
2188
|
+
className: "b316-social-button",
|
|
2189
|
+
"data-provider": option.slug,
|
|
2190
|
+
disabled,
|
|
2191
|
+
style: {
|
|
2192
|
+
background: option.buttonColor,
|
|
2193
|
+
color: option.buttonTextColor,
|
|
2194
|
+
borderColor: light ? "#747775" : option.buttonColor
|
|
2195
|
+
},
|
|
2196
|
+
onClick: () => onChoose(option),
|
|
2197
|
+
children: [
|
|
2198
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2199
|
+
"span",
|
|
2200
|
+
{
|
|
2201
|
+
className: "b316-social-icon",
|
|
2202
|
+
"aria-hidden": "true",
|
|
2203
|
+
dangerouslySetInnerHTML: { __html: icon }
|
|
2204
|
+
}
|
|
2205
|
+
) : null,
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: continueWith(option.name, option.provider) })
|
|
2207
|
+
]
|
|
2208
|
+
},
|
|
2209
|
+
option.slug
|
|
2210
|
+
);
|
|
2211
|
+
}) });
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
// src/SignIn.tsx
|
|
2215
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2216
|
+
var DEFAULT_SIGN_IN_LABELS = {
|
|
2217
|
+
email: "Email",
|
|
2218
|
+
password: "Password",
|
|
2219
|
+
mobileNumber: "Mobile number",
|
|
2220
|
+
code: "Code",
|
|
2221
|
+
tabPassword: "Password",
|
|
2222
|
+
tabMagicLink: "Magic link",
|
|
2223
|
+
tabPhone: "Text message",
|
|
2224
|
+
submit: "Sign in",
|
|
2225
|
+
working: "Working\u2026",
|
|
2226
|
+
emailMeALink: "Email me a link",
|
|
2227
|
+
textMeACode: "Text me a code",
|
|
2228
|
+
includeCountryCode: "Include the country code.",
|
|
2229
|
+
codeSent: (destination) => `We sent a code to ${destination}. It expires in ten minutes.`,
|
|
2230
|
+
useDifferentNumber: "Use a different number",
|
|
2231
|
+
or: "or",
|
|
2232
|
+
passkey: "Sign in with a passkey",
|
|
2233
|
+
continueWith: (name) => `Continue with ${name}`,
|
|
2234
|
+
sso: "Sign in with SSO",
|
|
2235
|
+
ssoEmail: "Work email",
|
|
2236
|
+
ssoContinue: "Continue",
|
|
2237
|
+
back: "Back",
|
|
2238
|
+
checkEmailTitle: "Check your email",
|
|
2239
|
+
checkEmail: (email) => `If an account exists for ${email}, a sign-in link is on its way. It expires shortly and can be used once.`,
|
|
2240
|
+
backToSignIn: "Back to sign in",
|
|
2241
|
+
wrongPassword: "That email and password did not match.",
|
|
2242
|
+
passkeyFailed: "That passkey did not work.",
|
|
2243
|
+
linkInvalid: "That sign-in link is no longer valid. Ask for a new one.",
|
|
2244
|
+
linkFailed: "We could not send that link. Try again.",
|
|
2245
|
+
wrongCode: "That code did not work. Check it, or ask for a new one.",
|
|
2246
|
+
codeFailed: "We could not send a code. Try again.",
|
|
2247
|
+
noMethods: "Signing in is not available right now."
|
|
2248
|
+
};
|
|
2067
2249
|
function SignIn({
|
|
2068
2250
|
onSignedIn,
|
|
2069
|
-
|
|
2251
|
+
password: passwordProp,
|
|
2252
|
+
passkeys: passkeysProp,
|
|
2253
|
+
magicLink: magicLinkProp,
|
|
2070
2254
|
magicLinkRedirectUrl,
|
|
2071
|
-
phone
|
|
2255
|
+
phone: phoneProp,
|
|
2256
|
+
social: socialProp,
|
|
2257
|
+
sso: ssoProp,
|
|
2258
|
+
socialRedirectUrl,
|
|
2259
|
+
socialState,
|
|
2260
|
+
labels: overrides,
|
|
2072
2261
|
secondFactorLabels,
|
|
2073
2262
|
className,
|
|
2074
2263
|
style
|
|
2075
2264
|
}) {
|
|
2265
|
+
const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
|
|
2076
2266
|
const { client, setToken } = useBase316();
|
|
2077
|
-
const
|
|
2078
|
-
const [
|
|
2079
|
-
const [
|
|
2080
|
-
const [
|
|
2267
|
+
const loaded = useSignInMethods(client);
|
|
2268
|
+
const [currentPage, setCurrentPage] = (0, import_react8.useState)(null);
|
|
2269
|
+
const [email, setEmail] = (0, import_react8.useState)("");
|
|
2270
|
+
const [password, setPassword] = (0, import_react8.useState)("");
|
|
2271
|
+
const [code, setCode] = (0, import_react8.useState)("");
|
|
2272
|
+
const [pending, setPending] = (0, import_react8.useState)(null);
|
|
2081
2273
|
const pendingChallenge = pending?.challengeToken ?? null;
|
|
2082
|
-
const [phoneNumber, setPhoneNumber] = (0,
|
|
2083
|
-
const [phoneChallenge, setPhoneChallenge] = (0,
|
|
2274
|
+
const [phoneNumber, setPhoneNumber] = (0, import_react8.useState)("");
|
|
2275
|
+
const [phoneChallenge, setPhoneChallenge] = (0, import_react8.useState)(
|
|
2084
2276
|
null
|
|
2085
2277
|
);
|
|
2086
|
-
const [error, setError] = (0,
|
|
2087
|
-
const [busy, setBusy] = (0,
|
|
2088
|
-
const [passkeyReady, setPasskeyReady] = (0,
|
|
2089
|
-
const [
|
|
2090
|
-
const [linkSent, setLinkSent] = (0,
|
|
2091
|
-
const abortRef = (0,
|
|
2278
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
2279
|
+
const [busy, setBusy] = (0, import_react8.useState)(false);
|
|
2280
|
+
const [passkeyReady, setPasskeyReady] = (0, import_react8.useState)(false);
|
|
2281
|
+
const [chosenMode, setMode] = (0, import_react8.useState)(null);
|
|
2282
|
+
const [linkSent, setLinkSent] = (0, import_react8.useState)(false);
|
|
2283
|
+
const abortRef = (0, import_react8.useRef)(null);
|
|
2284
|
+
(0, import_react8.useEffect)(() => {
|
|
2285
|
+
setCurrentPage(currentPageUrl());
|
|
2286
|
+
}, []);
|
|
2287
|
+
const offered = resolveMethods(
|
|
2288
|
+
loaded.methods,
|
|
2289
|
+
{
|
|
2290
|
+
password: passwordProp,
|
|
2291
|
+
passkeys: passkeysProp,
|
|
2292
|
+
magicLink: magicLinkProp,
|
|
2293
|
+
magicLinkRedirectUrl,
|
|
2294
|
+
phone: phoneProp,
|
|
2295
|
+
social: socialProp,
|
|
2296
|
+
sso: ssoProp,
|
|
2297
|
+
socialRedirectUrl
|
|
2298
|
+
},
|
|
2299
|
+
currentPage
|
|
2300
|
+
);
|
|
2301
|
+
const tabs = [
|
|
2302
|
+
...offered.password ? ["password"] : [],
|
|
2303
|
+
...offered.magicLink ? ["magic"] : [],
|
|
2304
|
+
...offered.phone ? ["phone"] : []
|
|
2305
|
+
];
|
|
2306
|
+
const mode = chosenMode && (chosenMode === "sso" ? offered.sso : tabs.includes(chosenMode)) ? chosenMode : tabs[0] ?? null;
|
|
2307
|
+
const passkeysWanted = loaded.status !== "loading" && offered.passkeys;
|
|
2092
2308
|
const signInWithPasskey = async (conditional, signal) => {
|
|
2093
2309
|
if (!conditional) {
|
|
2094
2310
|
setBusy(true);
|
|
@@ -2102,11 +2318,11 @@ function SignIn({
|
|
|
2102
2318
|
if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
|
|
2103
2319
|
return;
|
|
2104
2320
|
}
|
|
2105
|
-
if (cause instanceof
|
|
2321
|
+
if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
|
|
2106
2322
|
setError(cause.message);
|
|
2107
2323
|
} else if (!conditional) {
|
|
2108
2324
|
console.error("[base316] passkey sign-in failed", cause);
|
|
2109
|
-
setError(
|
|
2325
|
+
setError(labels.passkeyFailed);
|
|
2110
2326
|
}
|
|
2111
2327
|
} finally {
|
|
2112
2328
|
if (!conditional) {
|
|
@@ -2114,14 +2330,15 @@ function SignIn({
|
|
|
2114
2330
|
}
|
|
2115
2331
|
}
|
|
2116
2332
|
};
|
|
2117
|
-
(0,
|
|
2118
|
-
if (!
|
|
2333
|
+
(0, import_react8.useEffect)(() => {
|
|
2334
|
+
if (!passkeysWanted || !(0, import_sdk4.isPasskeySupported)() || pendingChallenge) {
|
|
2335
|
+
setPasskeyReady(false);
|
|
2119
2336
|
return;
|
|
2120
2337
|
}
|
|
2121
2338
|
setPasskeyReady(true);
|
|
2122
2339
|
const controller = new AbortController();
|
|
2123
2340
|
abortRef.current = controller;
|
|
2124
|
-
void (0,
|
|
2341
|
+
void (0, import_sdk4.isPasskeyAutofillAvailable)().then((available) => {
|
|
2125
2342
|
if (available && !controller.signal.aborted) {
|
|
2126
2343
|
void signInWithPasskey(true, controller.signal);
|
|
2127
2344
|
}
|
|
@@ -2129,8 +2346,8 @@ function SignIn({
|
|
|
2129
2346
|
return () => {
|
|
2130
2347
|
controller.abort();
|
|
2131
2348
|
};
|
|
2132
|
-
}, [
|
|
2133
|
-
(0,
|
|
2349
|
+
}, [passkeysWanted, pendingChallenge]);
|
|
2350
|
+
(0, import_react8.useEffect)(() => {
|
|
2134
2351
|
if (typeof window === "undefined") {
|
|
2135
2352
|
return;
|
|
2136
2353
|
}
|
|
@@ -2146,7 +2363,7 @@ function SignIn({
|
|
|
2146
2363
|
if (cancelled) {
|
|
2147
2364
|
return;
|
|
2148
2365
|
}
|
|
2149
|
-
if ((0,
|
|
2366
|
+
if ((0, import_sdk4.needsSecondFactor)(result)) {
|
|
2150
2367
|
setPending(result);
|
|
2151
2368
|
return;
|
|
2152
2369
|
}
|
|
@@ -2154,7 +2371,7 @@ function SignIn({
|
|
|
2154
2371
|
onSignedIn?.();
|
|
2155
2372
|
}).catch(() => {
|
|
2156
2373
|
if (!cancelled) {
|
|
2157
|
-
setError(
|
|
2374
|
+
setError(labels.linkInvalid);
|
|
2158
2375
|
}
|
|
2159
2376
|
});
|
|
2160
2377
|
return () => {
|
|
@@ -2162,23 +2379,44 @@ function SignIn({
|
|
|
2162
2379
|
};
|
|
2163
2380
|
}, []);
|
|
2164
2381
|
async function sendLink() {
|
|
2165
|
-
if (!
|
|
2382
|
+
if (!offered.magicLink) {
|
|
2166
2383
|
return;
|
|
2167
2384
|
}
|
|
2168
2385
|
setBusy(true);
|
|
2169
2386
|
setError(null);
|
|
2170
2387
|
try {
|
|
2171
|
-
await client.auth.magicLink.request({ email, redirectUrl:
|
|
2388
|
+
await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
|
|
2172
2389
|
setLinkSent(true);
|
|
2173
2390
|
} catch (cause) {
|
|
2174
2391
|
console.error("[base316] magic link request failed", cause);
|
|
2175
|
-
setError(
|
|
2392
|
+
setError(
|
|
2393
|
+
cause instanceof import_sdk4.Base316Error && cause.code === "INVALID_REQUEST" && cause.message ? cause.message : labels.linkFailed
|
|
2394
|
+
);
|
|
2176
2395
|
} finally {
|
|
2177
2396
|
setBusy(false);
|
|
2178
2397
|
}
|
|
2179
2398
|
}
|
|
2399
|
+
function leaveForSso() {
|
|
2400
|
+
if (!socialRedirectUrl) {
|
|
2401
|
+
return;
|
|
2402
|
+
}
|
|
2403
|
+
setBusy(true);
|
|
2404
|
+
beginRedirect(
|
|
2405
|
+
(state) => client.ssoSignInUrl({
|
|
2406
|
+
email,
|
|
2407
|
+
redirectUri: socialRedirectUrl,
|
|
2408
|
+
state,
|
|
2409
|
+
hostedUrl: offered.hostedUrl
|
|
2410
|
+
}),
|
|
2411
|
+
socialState
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2180
2414
|
async function submit(event) {
|
|
2181
2415
|
event.preventDefault();
|
|
2416
|
+
if (mode === "sso") {
|
|
2417
|
+
leaveForSso();
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2182
2420
|
setBusy(true);
|
|
2183
2421
|
setError(null);
|
|
2184
2422
|
try {
|
|
@@ -2196,7 +2434,7 @@ function SignIn({
|
|
|
2196
2434
|
challengeToken: phoneChallenge.token,
|
|
2197
2435
|
code
|
|
2198
2436
|
});
|
|
2199
|
-
if ((0,
|
|
2437
|
+
if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
|
|
2200
2438
|
setPending(signedIn);
|
|
2201
2439
|
setCode("");
|
|
2202
2440
|
return;
|
|
@@ -2206,7 +2444,7 @@ function SignIn({
|
|
|
2206
2444
|
return;
|
|
2207
2445
|
}
|
|
2208
2446
|
const result = await client.auth.signIn({ email, password });
|
|
2209
|
-
if ((0,
|
|
2447
|
+
if ((0, import_sdk4.needsSecondFactor)(result)) {
|
|
2210
2448
|
setPending(result);
|
|
2211
2449
|
return;
|
|
2212
2450
|
}
|
|
@@ -2215,25 +2453,23 @@ function SignIn({
|
|
|
2215
2453
|
} catch (cause) {
|
|
2216
2454
|
console.error("[base316] sign-in failed", cause);
|
|
2217
2455
|
setError(
|
|
2218
|
-
mode === "phone" ? phoneChallenge ?
|
|
2456
|
+
mode === "phone" ? phoneChallenge ? labels.wrongCode : (
|
|
2219
2457
|
// Why a text could not be sent is worth saying — a number in the
|
|
2220
2458
|
// wrong format, or too many requests — and the server words it
|
|
2221
2459
|
// without saying anything about accounts.
|
|
2222
|
-
cause instanceof Error && cause.message ? cause.message :
|
|
2460
|
+
cause instanceof Error && cause.message ? cause.message : labels.codeFailed
|
|
2223
2461
|
) : (
|
|
2224
2462
|
// An unconfirmed address and a throttle are worth naming; the
|
|
2225
2463
|
// server words both without saying whether an account exists.
|
|
2226
|
-
cause instanceof
|
|
2464
|
+
cause instanceof import_sdk4.Base316Error && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : labels.wrongPassword
|
|
2227
2465
|
)
|
|
2228
2466
|
);
|
|
2229
2467
|
} finally {
|
|
2230
2468
|
setBusy(false);
|
|
2231
2469
|
}
|
|
2232
2470
|
}
|
|
2233
|
-
const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
|
|
2234
|
-
const tabsShown = (magicAvailable || phone) && !pendingChallenge;
|
|
2235
2471
|
if (pending) {
|
|
2236
|
-
return /* @__PURE__ */ (0,
|
|
2472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2237
2473
|
SecondFactorStep,
|
|
2238
2474
|
{
|
|
2239
2475
|
pending,
|
|
@@ -2249,59 +2485,68 @@ function SignIn({
|
|
|
2249
2485
|
) });
|
|
2250
2486
|
}
|
|
2251
2487
|
if (linkSent) {
|
|
2252
|
-
return /* @__PURE__ */ (0,
|
|
2253
|
-
/* @__PURE__ */ (0,
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2255
|
-
|
|
2256
|
-
email,
|
|
2257
|
-
", a sign-in link is on its way. It expires shortly and can be used once."
|
|
2258
|
-
] }),
|
|
2259
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
2489
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 600, marginBottom: 6 }, children: labels.checkEmailTitle }),
|
|
2490
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-muted", children: labels.checkEmail(email) }),
|
|
2491
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2260
2492
|
"button",
|
|
2261
2493
|
{
|
|
2262
2494
|
type: "button",
|
|
2263
2495
|
className: "b316-button b316-button-secondary",
|
|
2264
2496
|
style: { marginTop: 16 },
|
|
2265
2497
|
onClick: () => setLinkSent(false),
|
|
2266
|
-
children:
|
|
2498
|
+
children: labels.backToSignIn
|
|
2267
2499
|
}
|
|
2268
2500
|
)
|
|
2269
2501
|
] });
|
|
2270
2502
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2503
|
+
const hasForm = mode !== null;
|
|
2504
|
+
const hasButtons = offered.social.length > 0 || passkeyReady || offered.sso && mode !== "sso";
|
|
2505
|
+
if (!hasForm && !hasButtons) {
|
|
2506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error ?? labels.noMethods }) });
|
|
2507
|
+
}
|
|
2508
|
+
const tabsShown = tabs.length > 1 && mode !== "sso";
|
|
2509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
|
|
2510
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
2511
|
+
offered.social.length > 0 && mode !== "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2512
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2513
|
+
SocialButtons,
|
|
2276
2514
|
{
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2515
|
+
options: offered.social,
|
|
2516
|
+
continueWith: labels.continueWith,
|
|
2517
|
+
disabled: busy,
|
|
2518
|
+
onChoose: (option) => {
|
|
2519
|
+
if (!socialRedirectUrl) {
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
setBusy(true);
|
|
2523
|
+
beginRedirect(
|
|
2524
|
+
(state) => client.socialSignInUrl({
|
|
2525
|
+
provider: option.slug,
|
|
2526
|
+
redirectUri: socialRedirectUrl,
|
|
2527
|
+
state,
|
|
2528
|
+
hostedUrl: offered.hostedUrl
|
|
2529
|
+
}),
|
|
2530
|
+
socialState
|
|
2531
|
+
);
|
|
2532
|
+
}
|
|
2281
2533
|
}
|
|
2282
2534
|
),
|
|
2283
|
-
|
|
2284
|
-
"button",
|
|
2285
|
-
{
|
|
2286
|
-
type: "button",
|
|
2287
|
-
className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
|
|
2288
|
-
onClick: () => setMode("magic"),
|
|
2289
|
-
children: "Magic link"
|
|
2290
|
-
}
|
|
2291
|
-
) : null,
|
|
2292
|
-
phone ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2293
|
-
"button",
|
|
2294
|
-
{
|
|
2295
|
-
type: "button",
|
|
2296
|
-
className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
|
|
2297
|
-
onClick: () => setMode("phone"),
|
|
2298
|
-
children: "Text message"
|
|
2299
|
-
}
|
|
2300
|
-
) : null
|
|
2535
|
+
hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null
|
|
2301
2536
|
] }) : null,
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2537
|
+
tabsShown ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-tabs", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2538
|
+
"button",
|
|
2539
|
+
{
|
|
2540
|
+
type: "button",
|
|
2541
|
+
className: cls("b316-tab", mode === tab ? "b316-tab-on" : void 0),
|
|
2542
|
+
onClick: () => setMode(tab),
|
|
2543
|
+
children: tab === "password" ? labels.tabPassword : tab === "magic" ? labels.tabMagicLink : labels.tabPhone
|
|
2544
|
+
},
|
|
2545
|
+
tab
|
|
2546
|
+
)) }) : null,
|
|
2547
|
+
mode === "phone" ? phoneChallenge ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2548
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-phone-code", children: labels.code }),
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2305
2550
|
"input",
|
|
2306
2551
|
{
|
|
2307
2552
|
id: "b316-phone-code",
|
|
@@ -2313,12 +2558,10 @@ function SignIn({
|
|
|
2313
2558
|
required: true
|
|
2314
2559
|
}
|
|
2315
2560
|
),
|
|
2316
|
-
/* @__PURE__ */ (0,
|
|
2317
|
-
|
|
2318
|
-
phoneChallenge.hint,
|
|
2319
|
-
". It expires in ten minutes.",
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "b316-muted", children: [
|
|
2562
|
+
labels.codeSent(phoneChallenge.hint),
|
|
2320
2563
|
" ",
|
|
2321
|
-
/* @__PURE__ */ (0,
|
|
2564
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2322
2565
|
"button",
|
|
2323
2566
|
{
|
|
2324
2567
|
type: "button",
|
|
@@ -2327,13 +2570,13 @@ function SignIn({
|
|
|
2327
2570
|
setPhoneChallenge(null);
|
|
2328
2571
|
setCode("");
|
|
2329
2572
|
},
|
|
2330
|
-
children:
|
|
2573
|
+
children: labels.useDifferentNumber
|
|
2331
2574
|
}
|
|
2332
2575
|
)
|
|
2333
2576
|
] })
|
|
2334
|
-
] }) : /* @__PURE__ */ (0,
|
|
2335
|
-
/* @__PURE__ */ (0,
|
|
2336
|
-
/* @__PURE__ */ (0,
|
|
2577
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2578
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-phone", children: labels.mobileNumber }),
|
|
2579
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2337
2580
|
"input",
|
|
2338
2581
|
{
|
|
2339
2582
|
id: "b316-phone",
|
|
@@ -2346,11 +2589,11 @@ function SignIn({
|
|
|
2346
2589
|
required: true
|
|
2347
2590
|
}
|
|
2348
2591
|
),
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2350
|
-
] }) : /* @__PURE__ */ (0,
|
|
2351
|
-
/* @__PURE__ */ (0,
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2353
|
-
/* @__PURE__ */ (0,
|
|
2592
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "b316-muted", children: labels.includeCountryCode })
|
|
2593
|
+
] }) : mode !== null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-email", children: mode === "sso" ? labels.ssoEmail : labels.email }),
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2354
2597
|
"input",
|
|
2355
2598
|
{
|
|
2356
2599
|
id: "b316-email",
|
|
@@ -2358,14 +2601,14 @@ function SignIn({
|
|
|
2358
2601
|
type: "email",
|
|
2359
2602
|
value: email,
|
|
2360
2603
|
onChange: (event) => setEmail(event.target.value),
|
|
2361
|
-
autoComplete: passkeyReady ? "email webauthn" : "email",
|
|
2604
|
+
autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
|
|
2362
2605
|
required: true
|
|
2363
2606
|
}
|
|
2364
2607
|
)
|
|
2365
2608
|
] }),
|
|
2366
|
-
mode === "password" ? /* @__PURE__ */ (0,
|
|
2367
|
-
/* @__PURE__ */ (0,
|
|
2368
|
-
/* @__PURE__ */ (0,
|
|
2609
|
+
mode === "password" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2610
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-password", children: labels.password }),
|
|
2611
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2369
2612
|
"input",
|
|
2370
2613
|
{
|
|
2371
2614
|
id: "b316-password",
|
|
@@ -2378,31 +2621,98 @@ function SignIn({
|
|
|
2378
2621
|
}
|
|
2379
2622
|
)
|
|
2380
2623
|
] }) : null
|
|
2381
|
-
] }),
|
|
2382
|
-
/* @__PURE__ */ (0,
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2624
|
+
] }) : null,
|
|
2625
|
+
mode !== null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : mode === "magic" ? labels.emailMeALink : mode === "phone" && !phoneChallenge ? labels.textMeACode : mode === "sso" ? labels.ssoContinue : labels.submit }) : null,
|
|
2626
|
+
mode === "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2627
|
+
"button",
|
|
2628
|
+
{
|
|
2629
|
+
type: "button",
|
|
2630
|
+
className: "b316-button b316-button-secondary",
|
|
2631
|
+
style: { marginTop: 10, width: "100%" },
|
|
2632
|
+
disabled: busy,
|
|
2633
|
+
onClick: () => setMode(null),
|
|
2634
|
+
children: labels.back
|
|
2635
|
+
}
|
|
2636
|
+
) : null,
|
|
2637
|
+
(passkeyReady || offered.sso) && mode !== "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2638
|
+
hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null,
|
|
2639
|
+
passkeyReady ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2386
2640
|
"button",
|
|
2387
2641
|
{
|
|
2388
2642
|
type: "button",
|
|
2389
2643
|
className: "b316-button b316-button-secondary",
|
|
2644
|
+
style: { width: "100%" },
|
|
2390
2645
|
disabled: busy,
|
|
2391
2646
|
onClick: () => {
|
|
2392
2647
|
abortRef.current?.abort();
|
|
2393
2648
|
void signInWithPasskey(false);
|
|
2394
2649
|
},
|
|
2395
|
-
children:
|
|
2650
|
+
children: labels.passkey
|
|
2396
2651
|
}
|
|
2397
|
-
)
|
|
2652
|
+
) : null,
|
|
2653
|
+
offered.sso ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2654
|
+
"button",
|
|
2655
|
+
{
|
|
2656
|
+
type: "button",
|
|
2657
|
+
className: "b316-button b316-button-secondary",
|
|
2658
|
+
style: { width: "100%", marginTop: passkeyReady ? 8 : 0 },
|
|
2659
|
+
disabled: busy,
|
|
2660
|
+
onClick: () => {
|
|
2661
|
+
abortRef.current?.abort();
|
|
2662
|
+
setError(null);
|
|
2663
|
+
setMode("sso");
|
|
2664
|
+
},
|
|
2665
|
+
children: labels.sso
|
|
2666
|
+
}
|
|
2667
|
+
) : null
|
|
2398
2668
|
] }) : null
|
|
2399
2669
|
] });
|
|
2400
2670
|
}
|
|
2401
2671
|
|
|
2672
|
+
// src/SocialSignIn.tsx
|
|
2673
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2674
|
+
function SocialSignIn({
|
|
2675
|
+
socialRedirectUrl,
|
|
2676
|
+
socialState,
|
|
2677
|
+
social,
|
|
2678
|
+
intent = "sign-in",
|
|
2679
|
+
divider = false,
|
|
2680
|
+
labels
|
|
2681
|
+
}) {
|
|
2682
|
+
const { client } = useBase316();
|
|
2683
|
+
const loaded = useSignInMethods(client);
|
|
2684
|
+
if (!loaded.methods || intent === "sign-up" && !loaded.methods.signUp) {
|
|
2685
|
+
return null;
|
|
2686
|
+
}
|
|
2687
|
+
const offered = resolveMethods(loaded.methods, { social, socialRedirectUrl }, null);
|
|
2688
|
+
if (!socialRedirectUrl || offered.social.length === 0) {
|
|
2689
|
+
return null;
|
|
2690
|
+
}
|
|
2691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2693
|
+
SocialButtons,
|
|
2694
|
+
{
|
|
2695
|
+
options: offered.social,
|
|
2696
|
+
continueWith: labels?.continueWith ?? ((name) => `Continue with ${name}`),
|
|
2697
|
+
onChoose: (option) => beginRedirect(
|
|
2698
|
+
(state) => client.socialSignInUrl({
|
|
2699
|
+
provider: option.slug,
|
|
2700
|
+
redirectUri: socialRedirectUrl,
|
|
2701
|
+
state,
|
|
2702
|
+
hostedUrl: offered.hostedUrl
|
|
2703
|
+
}),
|
|
2704
|
+
socialState
|
|
2705
|
+
)
|
|
2706
|
+
}
|
|
2707
|
+
),
|
|
2708
|
+
divider ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "b316-divider", children: labels?.or ?? "or" }) : null
|
|
2709
|
+
] });
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2402
2712
|
// src/SignUp.tsx
|
|
2403
|
-
var
|
|
2404
|
-
var
|
|
2405
|
-
var
|
|
2713
|
+
var import_sdk5 = require("@base316/sdk");
|
|
2714
|
+
var import_react9 = require("react");
|
|
2715
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2406
2716
|
var DEFAULT_SIGN_UP_LABELS = {
|
|
2407
2717
|
name: "Name",
|
|
2408
2718
|
email: "Email",
|
|
@@ -2419,7 +2729,10 @@ var DEFAULT_SIGN_UP_LABELS = {
|
|
|
2419
2729
|
confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
|
|
2420
2730
|
createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
|
|
2421
2731
|
genericError: "We could not create that account. Try again.",
|
|
2422
|
-
joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to
|
|
2732
|
+
joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
|
|
2733
|
+
continueWith: (name) => `Continue with ${name}`,
|
|
2734
|
+
or: "or",
|
|
2735
|
+
closed: "This application is not accepting new accounts right now."
|
|
2423
2736
|
};
|
|
2424
2737
|
function describeRules(policy, labels) {
|
|
2425
2738
|
const extras = [
|
|
@@ -2438,30 +2751,35 @@ function SignUp({
|
|
|
2438
2751
|
onJoined,
|
|
2439
2752
|
labels: overrides,
|
|
2440
2753
|
secondFactorLabels,
|
|
2754
|
+
social,
|
|
2755
|
+
socialRedirectUrl,
|
|
2756
|
+
socialState,
|
|
2441
2757
|
className,
|
|
2442
2758
|
style
|
|
2443
2759
|
}) {
|
|
2444
2760
|
const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
|
|
2445
2761
|
const { client, setToken } = useBase316();
|
|
2446
|
-
const
|
|
2447
|
-
const
|
|
2448
|
-
const [
|
|
2449
|
-
const [
|
|
2450
|
-
const [
|
|
2451
|
-
const [
|
|
2452
|
-
const [
|
|
2453
|
-
const [
|
|
2454
|
-
const [
|
|
2455
|
-
const [
|
|
2762
|
+
const methodsState = useSignInMethods(client);
|
|
2763
|
+
const offered = resolveMethods(methodsState.methods, { social, socialRedirectUrl }, null);
|
|
2764
|
+
const [name, setName] = (0, import_react9.useState)("");
|
|
2765
|
+
const [email, setEmail] = (0, import_react9.useState)("");
|
|
2766
|
+
const [password, setPassword] = (0, import_react9.useState)("");
|
|
2767
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
2768
|
+
const [busy, setBusy] = (0, import_react9.useState)(false);
|
|
2769
|
+
const [policy, setPolicy] = (0, import_react9.useState)(null);
|
|
2770
|
+
const [pending, setPending] = (0, import_react9.useState)(null);
|
|
2771
|
+
const [confirmEmail, setConfirmEmail] = (0, import_react9.useState)(false);
|
|
2772
|
+
const [urlInvitation, setUrlInvitation] = (0, import_react9.useState)(null);
|
|
2773
|
+
const [loaded, setLoaded] = (0, import_react9.useState)(null);
|
|
2456
2774
|
const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
|
|
2457
2775
|
const preview = loaded && loaded.token === invitation ? loaded.preview : null;
|
|
2458
|
-
(0,
|
|
2776
|
+
(0, import_react9.useEffect)(() => {
|
|
2459
2777
|
if (suppliedInvitation !== void 0 || typeof window === "undefined") {
|
|
2460
2778
|
return;
|
|
2461
2779
|
}
|
|
2462
2780
|
setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
|
|
2463
2781
|
}, [suppliedInvitation]);
|
|
2464
|
-
(0,
|
|
2782
|
+
(0, import_react9.useEffect)(() => {
|
|
2465
2783
|
if (!invitation) {
|
|
2466
2784
|
return;
|
|
2467
2785
|
}
|
|
@@ -2476,7 +2794,7 @@ function SignUp({
|
|
|
2476
2794
|
cancelled = true;
|
|
2477
2795
|
};
|
|
2478
2796
|
}, [client, invitation]);
|
|
2479
|
-
(0,
|
|
2797
|
+
(0, import_react9.useEffect)(() => {
|
|
2480
2798
|
let cancelled = false;
|
|
2481
2799
|
client.auth.passwordPolicy().then((loaded2) => {
|
|
2482
2800
|
if (!cancelled) {
|
|
@@ -2504,14 +2822,14 @@ function SignUp({
|
|
|
2504
2822
|
} catch (cause) {
|
|
2505
2823
|
console.error("[base316] sign-up failed", cause);
|
|
2506
2824
|
setError(
|
|
2507
|
-
cause instanceof
|
|
2825
|
+
cause instanceof import_sdk5.Base316Error && (cause.code === "INVALID_REQUEST" || cause.code === "RATE_LIMITED" || cause.code === "CONFLICT") && cause.message ? cause.message : labels.genericError
|
|
2508
2826
|
);
|
|
2509
2827
|
setBusy(false);
|
|
2510
2828
|
return;
|
|
2511
2829
|
}
|
|
2512
2830
|
try {
|
|
2513
2831
|
const signedIn = await client.auth.signIn({ email, password });
|
|
2514
|
-
if ((0,
|
|
2832
|
+
if ((0, import_sdk5.needsSecondFactor)(signedIn)) {
|
|
2515
2833
|
setPending(signedIn);
|
|
2516
2834
|
return;
|
|
2517
2835
|
}
|
|
@@ -2519,14 +2837,14 @@ function SignUp({
|
|
|
2519
2837
|
onSignedUp?.();
|
|
2520
2838
|
} catch (cause) {
|
|
2521
2839
|
console.error("[base316] sign-in after sign-up failed", cause);
|
|
2522
|
-
if (cause instanceof
|
|
2840
|
+
if (cause instanceof import_sdk5.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
|
|
2523
2841
|
setConfirmEmail(true);
|
|
2524
2842
|
onSignedUp?.();
|
|
2525
2843
|
return;
|
|
2526
2844
|
}
|
|
2527
2845
|
setError(
|
|
2528
2846
|
labels.createdSignInFailed(
|
|
2529
|
-
cause instanceof
|
|
2847
|
+
cause instanceof import_sdk5.Base316Error && cause.message ? cause.message : labels.genericError
|
|
2530
2848
|
)
|
|
2531
2849
|
);
|
|
2532
2850
|
} finally {
|
|
@@ -2534,86 +2852,118 @@ function SignUp({
|
|
|
2534
2852
|
}
|
|
2535
2853
|
}
|
|
2536
2854
|
if (pending) {
|
|
2537
|
-
return /* @__PURE__ */ (0,
|
|
2855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
|
|
2538
2856
|
}
|
|
2539
2857
|
if (confirmEmail) {
|
|
2540
|
-
return /* @__PURE__ */ (0,
|
|
2541
|
-
/* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.confirmEmail(email) })
|
|
2543
2861
|
] });
|
|
2544
2862
|
}
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
id: "b316-name",
|
|
2554
|
-
className: "b316-input",
|
|
2555
|
-
value: name,
|
|
2556
|
-
onChange: (event) => setName(event.target.value),
|
|
2557
|
-
autoComplete: "name"
|
|
2558
|
-
}
|
|
2559
|
-
)
|
|
2560
|
-
] }),
|
|
2561
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2562
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
|
|
2563
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2564
|
-
"input",
|
|
2565
|
-
{
|
|
2566
|
-
id: "b316-signup-email",
|
|
2567
|
-
className: "b316-input",
|
|
2568
|
-
type: "email",
|
|
2569
|
-
value: email,
|
|
2570
|
-
onChange: (event) => setEmail(event.target.value),
|
|
2571
|
-
autoComplete: "email",
|
|
2572
|
-
required: true
|
|
2573
|
-
}
|
|
2574
|
-
)
|
|
2575
|
-
] }),
|
|
2576
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2577
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
|
|
2578
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2579
|
-
"input",
|
|
2863
|
+
if (!offered.signUp && !invitation) {
|
|
2864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.closed }) });
|
|
2865
|
+
}
|
|
2866
|
+
const socialOptions = invitation ? [] : offered.social;
|
|
2867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
|
|
2868
|
+
socialOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2869
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2870
|
+
SocialButtons,
|
|
2580
2871
|
{
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2872
|
+
options: socialOptions,
|
|
2873
|
+
continueWith: labels.continueWith,
|
|
2874
|
+
disabled: busy,
|
|
2875
|
+
onChoose: (option) => {
|
|
2876
|
+
if (!socialRedirectUrl) {
|
|
2877
|
+
return;
|
|
2878
|
+
}
|
|
2879
|
+
setBusy(true);
|
|
2880
|
+
beginRedirect(
|
|
2881
|
+
(state) => client.socialSignInUrl({
|
|
2882
|
+
provider: option.slug,
|
|
2883
|
+
redirectUri: socialRedirectUrl,
|
|
2884
|
+
state,
|
|
2885
|
+
hostedUrl: offered.hostedUrl
|
|
2886
|
+
}),
|
|
2887
|
+
socialState
|
|
2888
|
+
);
|
|
2889
|
+
}
|
|
2591
2890
|
}
|
|
2592
2891
|
),
|
|
2593
|
-
|
|
2594
|
-
] }),
|
|
2595
|
-
/* @__PURE__ */ (0,
|
|
2892
|
+
offered.password ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-divider", children: labels.or }) : null
|
|
2893
|
+
] }) : null,
|
|
2894
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
|
|
2895
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
2896
|
+
offered.password || socialOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2897
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
|
|
2898
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2900
|
+
"input",
|
|
2901
|
+
{
|
|
2902
|
+
id: "b316-name",
|
|
2903
|
+
className: "b316-input",
|
|
2904
|
+
value: name,
|
|
2905
|
+
onChange: (event) => setName(event.target.value),
|
|
2906
|
+
autoComplete: "name"
|
|
2907
|
+
}
|
|
2908
|
+
)
|
|
2909
|
+
] }),
|
|
2910
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2913
|
+
"input",
|
|
2914
|
+
{
|
|
2915
|
+
id: "b316-signup-email",
|
|
2916
|
+
className: "b316-input",
|
|
2917
|
+
type: "email",
|
|
2918
|
+
value: email,
|
|
2919
|
+
onChange: (event) => setEmail(event.target.value),
|
|
2920
|
+
autoComplete: "email",
|
|
2921
|
+
required: true
|
|
2922
|
+
}
|
|
2923
|
+
)
|
|
2924
|
+
] }),
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
|
|
2926
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2928
|
+
"input",
|
|
2929
|
+
{
|
|
2930
|
+
id: "b316-signup-password",
|
|
2931
|
+
className: "b316-input",
|
|
2932
|
+
type: "password",
|
|
2933
|
+
value: password,
|
|
2934
|
+
onChange: (event) => setPassword(event.target.value),
|
|
2935
|
+
autoComplete: "new-password",
|
|
2936
|
+
minLength: policy?.minLength,
|
|
2937
|
+
maxLength: policy?.maxLength,
|
|
2938
|
+
"aria-describedby": policy ? "b316-signup-password-rules" : void 0,
|
|
2939
|
+
required: true
|
|
2940
|
+
}
|
|
2941
|
+
),
|
|
2942
|
+
policy ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
|
|
2943
|
+
] }),
|
|
2944
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
|
|
2945
|
+
] }) : null
|
|
2596
2946
|
] });
|
|
2597
2947
|
}
|
|
2598
2948
|
|
|
2599
2949
|
// src/UserProfile.tsx
|
|
2600
|
-
var
|
|
2950
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2601
2951
|
function UserProfile({ className, style }) {
|
|
2602
2952
|
const { session, loading, signOut } = useBase316();
|
|
2603
2953
|
if (loading) {
|
|
2604
|
-
return /* @__PURE__ */ (0,
|
|
2954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
2605
2955
|
}
|
|
2606
2956
|
if (!session) {
|
|
2607
|
-
return /* @__PURE__ */ (0,
|
|
2957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
|
|
2608
2958
|
}
|
|
2609
2959
|
const user = session.user ?? {};
|
|
2610
|
-
return /* @__PURE__ */ (0,
|
|
2611
|
-
/* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2613
|
-
user.name && user.email ? /* @__PURE__ */ (0,
|
|
2614
|
-
user.emailVerified === false ? /* @__PURE__ */ (0,
|
|
2960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-row", children: [
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2962
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
|
|
2963
|
+
user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: user.email }) : null,
|
|
2964
|
+
user.emailVerified === false ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: "Email not verified" }) : null
|
|
2615
2965
|
] }),
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2966
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2617
2967
|
"button",
|
|
2618
2968
|
{
|
|
2619
2969
|
type: "button",
|
|
@@ -2626,12 +2976,12 @@ function UserProfile({ className, style }) {
|
|
|
2626
2976
|
}
|
|
2627
2977
|
|
|
2628
2978
|
// src/PasskeyManager.tsx
|
|
2629
|
-
var
|
|
2630
|
-
var
|
|
2979
|
+
var import_sdk6 = require("@base316/sdk");
|
|
2980
|
+
var import_react11 = require("react");
|
|
2631
2981
|
|
|
2632
2982
|
// src/confirm.tsx
|
|
2633
|
-
var
|
|
2634
|
-
var
|
|
2983
|
+
var import_react10 = require("react");
|
|
2984
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2635
2985
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
2636
2986
|
function ConfirmButton({
|
|
2637
2987
|
children,
|
|
@@ -2641,9 +2991,9 @@ function ConfirmButton({
|
|
|
2641
2991
|
disabled,
|
|
2642
2992
|
timeoutMs = DEFAULT_TIMEOUT_MS
|
|
2643
2993
|
}) {
|
|
2644
|
-
const [armed, setArmed] = (0,
|
|
2645
|
-
const confirmRef = (0,
|
|
2646
|
-
(0,
|
|
2994
|
+
const [armed, setArmed] = (0, import_react10.useState)(false);
|
|
2995
|
+
const confirmRef = (0, import_react10.useRef)(null);
|
|
2996
|
+
(0, import_react10.useEffect)(() => {
|
|
2647
2997
|
if (!armed) {
|
|
2648
2998
|
return;
|
|
2649
2999
|
}
|
|
@@ -2652,7 +3002,7 @@ function ConfirmButton({
|
|
|
2652
3002
|
return () => clearTimeout(timer);
|
|
2653
3003
|
}, [armed, timeoutMs]);
|
|
2654
3004
|
if (!armed) {
|
|
2655
|
-
return /* @__PURE__ */ (0,
|
|
3005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2656
3006
|
"button",
|
|
2657
3007
|
{
|
|
2658
3008
|
type: "button",
|
|
@@ -2666,8 +3016,8 @@ function ConfirmButton({
|
|
|
2666
3016
|
return (
|
|
2667
3017
|
// No `role="group"`: both buttons already say what they do, and the
|
|
2668
3018
|
// grouping would only repeat the question a screen reader has just read.
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
3019
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "b316-confirm", children: [
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2671
3021
|
"button",
|
|
2672
3022
|
{
|
|
2673
3023
|
ref: confirmRef,
|
|
@@ -2681,7 +3031,7 @@ function ConfirmButton({
|
|
|
2681
3031
|
children: confirmLabel
|
|
2682
3032
|
}
|
|
2683
3033
|
),
|
|
2684
|
-
/* @__PURE__ */ (0,
|
|
3034
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2685
3035
|
"button",
|
|
2686
3036
|
{
|
|
2687
3037
|
type: "button",
|
|
@@ -2695,19 +3045,19 @@ function ConfirmButton({
|
|
|
2695
3045
|
}
|
|
2696
3046
|
|
|
2697
3047
|
// src/PasskeyManager.tsx
|
|
2698
|
-
var
|
|
3048
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2699
3049
|
function PasskeyManager({
|
|
2700
3050
|
className,
|
|
2701
3051
|
style,
|
|
2702
3052
|
title = "Passkeys"
|
|
2703
3053
|
}) {
|
|
2704
3054
|
const { client, token, session } = useBase316();
|
|
2705
|
-
const [passkeys, setPasskeys] = (0,
|
|
2706
|
-
const [busy, setBusy] = (0,
|
|
2707
|
-
const [error, setError] = (0,
|
|
2708
|
-
const [name, setName] = (0,
|
|
2709
|
-
const [supported, setSupported] = (0,
|
|
2710
|
-
const load = (0,
|
|
3055
|
+
const [passkeys, setPasskeys] = (0, import_react11.useState)(null);
|
|
3056
|
+
const [busy, setBusy] = (0, import_react11.useState)(false);
|
|
3057
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
3058
|
+
const [name, setName] = (0, import_react11.useState)("");
|
|
3059
|
+
const [supported, setSupported] = (0, import_react11.useState)(false);
|
|
3060
|
+
const load = (0, import_react11.useCallback)(async () => {
|
|
2711
3061
|
if (!token) {
|
|
2712
3062
|
return;
|
|
2713
3063
|
}
|
|
@@ -2720,8 +3070,8 @@ function PasskeyManager({
|
|
|
2720
3070
|
setPasskeys(null);
|
|
2721
3071
|
}
|
|
2722
3072
|
}, [client, token]);
|
|
2723
|
-
(0,
|
|
2724
|
-
if (!(0,
|
|
3073
|
+
(0, import_react11.useEffect)(() => {
|
|
3074
|
+
if (!(0, import_sdk6.isPasskeySupported)()) {
|
|
2725
3075
|
return;
|
|
2726
3076
|
}
|
|
2727
3077
|
setSupported(true);
|
|
@@ -2756,18 +3106,18 @@ function PasskeyManager({
|
|
|
2756
3106
|
setError(caught instanceof Error ? caught.message : "That did not work.");
|
|
2757
3107
|
}
|
|
2758
3108
|
};
|
|
2759
|
-
return /* @__PURE__ */ (0,
|
|
2760
|
-
/* @__PURE__ */ (0,
|
|
2761
|
-
/* @__PURE__ */ (0,
|
|
2762
|
-
passkeys === null ? /* @__PURE__ */ (0,
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
3109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
3110
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
|
|
3111
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
|
|
3112
|
+
passkeys === null ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: passkey.name || "Passkey" }),
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-muted", children: [
|
|
2766
3116
|
passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
|
|
2767
3117
|
passkey.backedUp ? "" : " \xB7 this device only"
|
|
2768
3118
|
] })
|
|
2769
3119
|
] }),
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
3120
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2771
3121
|
ConfirmButton,
|
|
2772
3122
|
{
|
|
2773
3123
|
className: "b316-button b316-button-secondary",
|
|
@@ -2777,9 +3127,9 @@ function PasskeyManager({
|
|
|
2777
3127
|
}
|
|
2778
3128
|
)
|
|
2779
3129
|
] }, passkey.id)) }),
|
|
2780
|
-
error ? /* @__PURE__ */ (0,
|
|
2781
|
-
/* @__PURE__ */ (0,
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
3130
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
|
|
3131
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
|
|
3132
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2783
3133
|
"input",
|
|
2784
3134
|
{
|
|
2785
3135
|
className: "b316-input",
|
|
@@ -2788,7 +3138,7 @@ function PasskeyManager({
|
|
|
2788
3138
|
onChange: (event) => setName(event.target.value)
|
|
2789
3139
|
}
|
|
2790
3140
|
),
|
|
2791
|
-
/* @__PURE__ */ (0,
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
|
|
2792
3142
|
] })
|
|
2793
3143
|
] });
|
|
2794
3144
|
}
|
|
@@ -2798,8 +3148,8 @@ function formatDate(value) {
|
|
|
2798
3148
|
}
|
|
2799
3149
|
|
|
2800
3150
|
// src/ActiveSessions.tsx
|
|
2801
|
-
var
|
|
2802
|
-
var
|
|
3151
|
+
var import_react12 = require("react");
|
|
3152
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2803
3153
|
function describeDevice(userAgent) {
|
|
2804
3154
|
if (!userAgent) {
|
|
2805
3155
|
return null;
|
|
@@ -2817,10 +3167,10 @@ function when(value) {
|
|
|
2817
3167
|
}
|
|
2818
3168
|
function ActiveSessions({ onRevoked, className, style }) {
|
|
2819
3169
|
const { client, token } = useBase316();
|
|
2820
|
-
const [sessions, setSessions] = (0,
|
|
2821
|
-
const [error, setError] = (0,
|
|
2822
|
-
const [busy, setBusy] = (0,
|
|
2823
|
-
const load = (0,
|
|
3170
|
+
const [sessions, setSessions] = (0, import_react12.useState)(null);
|
|
3171
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
3172
|
+
const [busy, setBusy] = (0, import_react12.useState)(false);
|
|
3173
|
+
const load = (0, import_react12.useCallback)(() => {
|
|
2824
3174
|
if (!token) {
|
|
2825
3175
|
return;
|
|
2826
3176
|
}
|
|
@@ -2831,15 +3181,15 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
2831
3181
|
setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
|
|
2832
3182
|
});
|
|
2833
3183
|
}, [client, token]);
|
|
2834
|
-
(0,
|
|
3184
|
+
(0, import_react12.useEffect)(load, [load]);
|
|
2835
3185
|
if (!token) {
|
|
2836
3186
|
return null;
|
|
2837
3187
|
}
|
|
2838
3188
|
if (error) {
|
|
2839
|
-
return /* @__PURE__ */ (0,
|
|
3189
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
2840
3190
|
}
|
|
2841
3191
|
if (!sessions) {
|
|
2842
|
-
return /* @__PURE__ */ (0,
|
|
3192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
2843
3193
|
}
|
|
2844
3194
|
async function revokeOthers() {
|
|
2845
3195
|
setBusy(true);
|
|
@@ -2853,32 +3203,32 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
2853
3203
|
setBusy(false);
|
|
2854
3204
|
}
|
|
2855
3205
|
}
|
|
2856
|
-
return /* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2859
|
-
sessions.length > 1 ? /* @__PURE__ */ (0,
|
|
3206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
|
|
3207
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-sessions-head", children: [
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
|
|
3209
|
+
sessions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
|
|
2860
3210
|
] }),
|
|
2861
|
-
/* @__PURE__ */ (0,
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
3211
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("li", { className: "b316-session", children: [
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-session-device", children: [
|
|
2863
3213
|
describeDevice(session.userAgent) ?? "Unknown device",
|
|
2864
3214
|
session.impersonatedBy ? (
|
|
2865
3215
|
// Worth saying loudly: somebody is acting as this account.
|
|
2866
|
-
/* @__PURE__ */ (0,
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "b316-chip", children: " Support access" })
|
|
2867
3217
|
) : null
|
|
2868
3218
|
] }),
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
|
|
2870
3220
|
session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
|
|
2871
3221
|
"last used ",
|
|
2872
3222
|
when(session.lastSeenAt)
|
|
2873
3223
|
] })
|
|
2874
3224
|
] }, session.id)) }),
|
|
2875
|
-
sessions.length === 0 ? /* @__PURE__ */ (0,
|
|
3225
|
+
sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
|
|
2876
3226
|
] });
|
|
2877
3227
|
}
|
|
2878
3228
|
|
|
2879
3229
|
// src/DeviceApproval.tsx
|
|
2880
|
-
var
|
|
2881
|
-
var
|
|
3230
|
+
var import_react13 = require("react");
|
|
3231
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2882
3232
|
function DeviceApproval({
|
|
2883
3233
|
userCode = "",
|
|
2884
3234
|
onDecided,
|
|
@@ -2886,11 +3236,11 @@ function DeviceApproval({
|
|
|
2886
3236
|
style
|
|
2887
3237
|
}) {
|
|
2888
3238
|
const { client, token } = useBase316();
|
|
2889
|
-
const [code, setCode] = (0,
|
|
2890
|
-
const [request, setRequest] = (0,
|
|
2891
|
-
const [decided, setDecided] = (0,
|
|
2892
|
-
const [error, setError] = (0,
|
|
2893
|
-
const [busy, setBusy] = (0,
|
|
3239
|
+
const [code, setCode] = (0, import_react13.useState)(userCode);
|
|
3240
|
+
const [request, setRequest] = (0, import_react13.useState)(null);
|
|
3241
|
+
const [decided, setDecided] = (0, import_react13.useState)(null);
|
|
3242
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
3243
|
+
const [busy, setBusy] = (0, import_react13.useState)(false);
|
|
2894
3244
|
if (!token) {
|
|
2895
3245
|
return null;
|
|
2896
3246
|
}
|
|
@@ -2923,25 +3273,25 @@ function DeviceApproval({
|
|
|
2923
3273
|
}
|
|
2924
3274
|
}
|
|
2925
3275
|
if (decided !== null) {
|
|
2926
|
-
return /* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
3276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
|
|
3277
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
|
|
3278
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
|
|
2929
3279
|
] });
|
|
2930
3280
|
}
|
|
2931
3281
|
if (request) {
|
|
2932
|
-
return /* @__PURE__ */ (0,
|
|
2933
|
-
/* @__PURE__ */ (0,
|
|
3282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
|
|
3283
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("h3", { className: "b316-device-title", children: [
|
|
2934
3284
|
"Sign in to ",
|
|
2935
3285
|
request.clientName
|
|
2936
3286
|
] }),
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
3287
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "b316-muted", children: [
|
|
2938
3288
|
request.clientName,
|
|
2939
3289
|
" is asking to sign in as you."
|
|
2940
3290
|
] }),
|
|
2941
|
-
request.scopes.length > 0 ? /* @__PURE__ */ (0,
|
|
2942
|
-
error ? /* @__PURE__ */ (0,
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
2944
|
-
/* @__PURE__ */ (0,
|
|
3291
|
+
request.scopes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: scope }, scope)) }) : null,
|
|
3292
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3293
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-device-actions", children: [
|
|
3294
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2945
3295
|
"button",
|
|
2946
3296
|
{
|
|
2947
3297
|
type: "button",
|
|
@@ -2951,7 +3301,7 @@ function DeviceApproval({
|
|
|
2951
3301
|
children: busy ? "Approving\u2026" : "Approve"
|
|
2952
3302
|
}
|
|
2953
3303
|
),
|
|
2954
|
-
/* @__PURE__ */ (0,
|
|
3304
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2955
3305
|
"button",
|
|
2956
3306
|
{
|
|
2957
3307
|
type: "button",
|
|
@@ -2964,11 +3314,11 @@ function DeviceApproval({
|
|
|
2964
3314
|
] })
|
|
2965
3315
|
] });
|
|
2966
3316
|
}
|
|
2967
|
-
return /* @__PURE__ */ (0,
|
|
2968
|
-
/* @__PURE__ */ (0,
|
|
2969
|
-
/* @__PURE__ */ (0,
|
|
2970
|
-
error ? /* @__PURE__ */ (0,
|
|
2971
|
-
/* @__PURE__ */ (0,
|
|
3317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
|
|
3318
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
|
|
3319
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
|
|
3320
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3321
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2972
3322
|
"input",
|
|
2973
3323
|
{
|
|
2974
3324
|
className: "b316-input",
|
|
@@ -2981,13 +3331,13 @@ function DeviceApproval({
|
|
|
2981
3331
|
"aria-label": "Device code"
|
|
2982
3332
|
}
|
|
2983
3333
|
),
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
3334
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
|
|
2985
3335
|
] });
|
|
2986
3336
|
}
|
|
2987
3337
|
|
|
2988
3338
|
// src/PrivacyControls.tsx
|
|
2989
|
-
var
|
|
2990
|
-
var
|
|
3339
|
+
var import_react14 = require("react");
|
|
3340
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2991
3341
|
function PrivacyControls({
|
|
2992
3342
|
confirmWord = "DELETE",
|
|
2993
3343
|
onErased,
|
|
@@ -2995,10 +3345,10 @@ function PrivacyControls({
|
|
|
2995
3345
|
style
|
|
2996
3346
|
}) {
|
|
2997
3347
|
const { client, token } = useBase316();
|
|
2998
|
-
const [confirming, setConfirming] = (0,
|
|
2999
|
-
const [typed, setTyped] = (0,
|
|
3000
|
-
const [error, setError] = (0,
|
|
3001
|
-
const [busy, setBusy] = (0,
|
|
3348
|
+
const [confirming, setConfirming] = (0, import_react14.useState)(false);
|
|
3349
|
+
const [typed, setTyped] = (0, import_react14.useState)("");
|
|
3350
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
3351
|
+
const [busy, setBusy] = (0, import_react14.useState)(false);
|
|
3002
3352
|
if (!token) {
|
|
3003
3353
|
return null;
|
|
3004
3354
|
}
|
|
@@ -3033,22 +3383,22 @@ function PrivacyControls({
|
|
|
3033
3383
|
setBusy(false);
|
|
3034
3384
|
}
|
|
3035
3385
|
}
|
|
3036
|
-
return /* @__PURE__ */ (0,
|
|
3037
|
-
/* @__PURE__ */ (0,
|
|
3038
|
-
error ? /* @__PURE__ */ (0,
|
|
3039
|
-
/* @__PURE__ */ (0,
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3041
|
-
/* @__PURE__ */ (0,
|
|
3042
|
-
/* @__PURE__ */ (0,
|
|
3386
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
|
|
3388
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3389
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
|
|
3390
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
3391
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Download a copy" }),
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
|
|
3043
3393
|
] }),
|
|
3044
|
-
/* @__PURE__ */ (0,
|
|
3394
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
|
|
3045
3395
|
] }),
|
|
3046
|
-
/* @__PURE__ */ (0,
|
|
3047
|
-
/* @__PURE__ */ (0,
|
|
3048
|
-
/* @__PURE__ */ (0,
|
|
3049
|
-
/* @__PURE__ */ (0,
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Delete your account" }),
|
|
3399
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
|
|
3050
3400
|
] }),
|
|
3051
|
-
confirming ? null : /* @__PURE__ */ (0,
|
|
3401
|
+
confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3052
3402
|
"button",
|
|
3053
3403
|
{
|
|
3054
3404
|
type: "button",
|
|
@@ -3059,13 +3409,13 @@ function PrivacyControls({
|
|
|
3059
3409
|
}
|
|
3060
3410
|
)
|
|
3061
3411
|
] }),
|
|
3062
|
-
confirming ? /* @__PURE__ */ (0,
|
|
3063
|
-
/* @__PURE__ */ (0,
|
|
3412
|
+
confirming ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-confirm", children: [
|
|
3413
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
|
|
3064
3414
|
"Type ",
|
|
3065
3415
|
confirmWord,
|
|
3066
3416
|
" to confirm"
|
|
3067
3417
|
] }),
|
|
3068
|
-
/* @__PURE__ */ (0,
|
|
3418
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3069
3419
|
"input",
|
|
3070
3420
|
{
|
|
3071
3421
|
id: "b316-privacy-confirm",
|
|
@@ -3075,8 +3425,8 @@ function PrivacyControls({
|
|
|
3075
3425
|
onChange: (event) => setTyped(event.target.value)
|
|
3076
3426
|
}
|
|
3077
3427
|
),
|
|
3078
|
-
/* @__PURE__ */ (0,
|
|
3079
|
-
/* @__PURE__ */ (0,
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-actions", children: [
|
|
3429
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3080
3430
|
"button",
|
|
3081
3431
|
{
|
|
3082
3432
|
type: "button",
|
|
@@ -3088,7 +3438,7 @@ function PrivacyControls({
|
|
|
3088
3438
|
children: "Cancel"
|
|
3089
3439
|
}
|
|
3090
3440
|
),
|
|
3091
|
-
/* @__PURE__ */ (0,
|
|
3441
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3092
3442
|
"button",
|
|
3093
3443
|
{
|
|
3094
3444
|
type: "button",
|
|
@@ -3104,12 +3454,12 @@ function PrivacyControls({
|
|
|
3104
3454
|
}
|
|
3105
3455
|
|
|
3106
3456
|
// src/TwoFactorManager.tsx
|
|
3107
|
-
var
|
|
3457
|
+
var import_react16 = require("react");
|
|
3108
3458
|
|
|
3109
3459
|
// src/QrCode.tsx
|
|
3110
3460
|
var import_qrcode_generator = __toESM(require("qrcode-generator"));
|
|
3111
|
-
var
|
|
3112
|
-
var
|
|
3461
|
+
var import_react15 = require("react");
|
|
3462
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3113
3463
|
var QUIET_ZONE = 4;
|
|
3114
3464
|
function utf8Binary(value) {
|
|
3115
3465
|
let binary = "";
|
|
@@ -3134,9 +3484,9 @@ function qrPath(value) {
|
|
|
3134
3484
|
return { path, modules };
|
|
3135
3485
|
}
|
|
3136
3486
|
function QrCode({ value, label, size = 180, className }) {
|
|
3137
|
-
const { path, modules } = (0,
|
|
3487
|
+
const { path, modules } = (0, import_react15.useMemo)(() => qrPath(value), [value]);
|
|
3138
3488
|
const extent = modules + QUIET_ZONE * 2;
|
|
3139
|
-
return /* @__PURE__ */ (0,
|
|
3489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3140
3490
|
"svg",
|
|
3141
3491
|
{
|
|
3142
3492
|
className,
|
|
@@ -3148,15 +3498,15 @@ function QrCode({ value, label, size = 180, className }) {
|
|
|
3148
3498
|
shapeRendering: "crispEdges",
|
|
3149
3499
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3150
3500
|
children: [
|
|
3151
|
-
/* @__PURE__ */ (0,
|
|
3152
|
-
/* @__PURE__ */ (0,
|
|
3501
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
|
|
3502
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: path, fill: "#000000" })
|
|
3153
3503
|
]
|
|
3154
3504
|
}
|
|
3155
3505
|
);
|
|
3156
3506
|
}
|
|
3157
3507
|
|
|
3158
3508
|
// src/TwoFactorManager.tsx
|
|
3159
|
-
var
|
|
3509
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3160
3510
|
function groupKey(secret) {
|
|
3161
3511
|
return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
|
|
3162
3512
|
}
|
|
@@ -3169,12 +3519,12 @@ function TwoFactorManager({
|
|
|
3169
3519
|
style
|
|
3170
3520
|
}) {
|
|
3171
3521
|
const { client, token } = useBase316();
|
|
3172
|
-
const [stage, setStage] = (0,
|
|
3173
|
-
const [on, setOn] = (0,
|
|
3174
|
-
const [code, setCode] = (0,
|
|
3175
|
-
const [phone, setPhone] = (0,
|
|
3176
|
-
const [error, setError] = (0,
|
|
3177
|
-
const [busy, setBusy] = (0,
|
|
3522
|
+
const [stage, setStage] = (0, import_react16.useState)({ name: "idle" });
|
|
3523
|
+
const [on, setOn] = (0, import_react16.useState)(enabled);
|
|
3524
|
+
const [code, setCode] = (0, import_react16.useState)("");
|
|
3525
|
+
const [phone, setPhone] = (0, import_react16.useState)("");
|
|
3526
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
3527
|
+
const [busy, setBusy] = (0, import_react16.useState)(false);
|
|
3178
3528
|
if (!token) {
|
|
3179
3529
|
return null;
|
|
3180
3530
|
}
|
|
@@ -3252,17 +3602,17 @@ function TwoFactorManager({
|
|
|
3252
3602
|
setBusy(false);
|
|
3253
3603
|
}
|
|
3254
3604
|
}
|
|
3255
|
-
return /* @__PURE__ */ (0,
|
|
3256
|
-
/* @__PURE__ */ (0,
|
|
3257
|
-
error ? /* @__PURE__ */ (0,
|
|
3258
|
-
stage.name === "saved" ? /* @__PURE__ */ (0,
|
|
3259
|
-
/* @__PURE__ */ (0,
|
|
3260
|
-
/* @__PURE__ */ (0,
|
|
3261
|
-
/* @__PURE__ */ (0,
|
|
3262
|
-
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0,
|
|
3263
|
-
/* @__PURE__ */ (0,
|
|
3264
|
-
/* @__PURE__ */ (0,
|
|
3265
|
-
/* @__PURE__ */ (0,
|
|
3605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
|
|
3606
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
|
|
3607
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3608
|
+
stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-codes", children: [
|
|
3609
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
|
|
3610
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { children: recovery }) }, recovery)) }),
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
|
|
3612
|
+
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
|
|
3613
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3266
3616
|
"input",
|
|
3267
3617
|
{
|
|
3268
3618
|
id: "b316-mfa-phone",
|
|
@@ -3274,8 +3624,8 @@ function TwoFactorManager({
|
|
|
3274
3624
|
onChange: (event) => setPhone(event.target.value)
|
|
3275
3625
|
}
|
|
3276
3626
|
),
|
|
3277
|
-
/* @__PURE__ */ (0,
|
|
3278
|
-
/* @__PURE__ */ (0,
|
|
3627
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3628
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3279
3629
|
"button",
|
|
3280
3630
|
{
|
|
3281
3631
|
type: "button",
|
|
@@ -3284,16 +3634,16 @@ function TwoFactorManager({
|
|
|
3284
3634
|
children: "Cancel"
|
|
3285
3635
|
}
|
|
3286
3636
|
),
|
|
3287
|
-
/* @__PURE__ */ (0,
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
|
|
3288
3638
|
] })
|
|
3289
|
-
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0,
|
|
3290
|
-
/* @__PURE__ */ (0,
|
|
3639
|
+
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { children: [
|
|
3291
3641
|
"We sent a code to ",
|
|
3292
3642
|
stage.destinationHint,
|
|
3293
3643
|
". Enter it below to turn this on."
|
|
3294
3644
|
] }),
|
|
3295
|
-
/* @__PURE__ */ (0,
|
|
3296
|
-
/* @__PURE__ */ (0,
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3646
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3297
3647
|
"input",
|
|
3298
3648
|
{
|
|
3299
3649
|
id: "b316-mfa-code",
|
|
@@ -3304,8 +3654,8 @@ function TwoFactorManager({
|
|
|
3304
3654
|
onChange: (event) => setCode(event.target.value)
|
|
3305
3655
|
}
|
|
3306
3656
|
),
|
|
3307
|
-
/* @__PURE__ */ (0,
|
|
3308
|
-
/* @__PURE__ */ (0,
|
|
3657
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3658
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3309
3659
|
"button",
|
|
3310
3660
|
{
|
|
3311
3661
|
type: "button",
|
|
@@ -3314,7 +3664,7 @@ function TwoFactorManager({
|
|
|
3314
3664
|
children: "Cancel"
|
|
3315
3665
|
}
|
|
3316
3666
|
),
|
|
3317
|
-
/* @__PURE__ */ (0,
|
|
3667
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3318
3668
|
"button",
|
|
3319
3669
|
{
|
|
3320
3670
|
type: "button",
|
|
@@ -3325,9 +3675,9 @@ function TwoFactorManager({
|
|
|
3325
3675
|
}
|
|
3326
3676
|
)
|
|
3327
3677
|
] })
|
|
3328
|
-
] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0,
|
|
3329
|
-
/* @__PURE__ */ (0,
|
|
3330
|
-
/* @__PURE__ */ (0,
|
|
3678
|
+
] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
|
|
3679
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
|
|
3680
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3331
3681
|
QrCode,
|
|
3332
3682
|
{
|
|
3333
3683
|
className: "b316-mfa-qr",
|
|
@@ -3335,13 +3685,13 @@ function TwoFactorManager({
|
|
|
3335
3685
|
label: "QR code for your authenticator app"
|
|
3336
3686
|
}
|
|
3337
3687
|
),
|
|
3338
|
-
/* @__PURE__ */ (0,
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-secret", children: [
|
|
3689
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
|
|
3690
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
|
|
3341
3691
|
] }),
|
|
3342
|
-
/* @__PURE__ */ (0,
|
|
3343
|
-
/* @__PURE__ */ (0,
|
|
3344
|
-
/* @__PURE__ */ (0,
|
|
3692
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
|
|
3693
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3694
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3345
3695
|
"input",
|
|
3346
3696
|
{
|
|
3347
3697
|
id: "b316-mfa-code",
|
|
@@ -3352,8 +3702,8 @@ function TwoFactorManager({
|
|
|
3352
3702
|
onChange: (event) => setCode(event.target.value)
|
|
3353
3703
|
}
|
|
3354
3704
|
),
|
|
3355
|
-
/* @__PURE__ */ (0,
|
|
3356
|
-
/* @__PURE__ */ (0,
|
|
3705
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3706
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3357
3707
|
"button",
|
|
3358
3708
|
{
|
|
3359
3709
|
type: "button",
|
|
@@ -3362,7 +3712,7 @@ function TwoFactorManager({
|
|
|
3362
3712
|
children: "Cancel"
|
|
3363
3713
|
}
|
|
3364
3714
|
),
|
|
3365
|
-
/* @__PURE__ */ (0,
|
|
3715
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3366
3716
|
"button",
|
|
3367
3717
|
{
|
|
3368
3718
|
type: "button",
|
|
@@ -3373,9 +3723,9 @@ function TwoFactorManager({
|
|
|
3373
3723
|
}
|
|
3374
3724
|
)
|
|
3375
3725
|
] })
|
|
3376
|
-
] }) : on ? /* @__PURE__ */ (0,
|
|
3377
|
-
/* @__PURE__ */ (0,
|
|
3378
|
-
/* @__PURE__ */ (0,
|
|
3726
|
+
] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-on", children: [
|
|
3727
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
|
|
3728
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3379
3729
|
ConfirmButton,
|
|
3380
3730
|
{
|
|
3381
3731
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3385,11 +3735,11 @@ function TwoFactorManager({
|
|
|
3385
3735
|
children: "Turn off"
|
|
3386
3736
|
}
|
|
3387
3737
|
)
|
|
3388
|
-
] }) : /* @__PURE__ */ (0,
|
|
3389
|
-
/* @__PURE__ */ (0,
|
|
3390
|
-
/* @__PURE__ */ (0,
|
|
3391
|
-
/* @__PURE__ */ (0,
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3738
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-off", children: [
|
|
3739
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
|
|
3740
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3741
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3393
3743
|
"button",
|
|
3394
3744
|
{
|
|
3395
3745
|
type: "button",
|
|
@@ -3399,7 +3749,7 @@ function TwoFactorManager({
|
|
|
3399
3749
|
children: "Email me a code"
|
|
3400
3750
|
}
|
|
3401
3751
|
),
|
|
3402
|
-
allowSms ? /* @__PURE__ */ (0,
|
|
3752
|
+
allowSms ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3403
3753
|
"button",
|
|
3404
3754
|
{
|
|
3405
3755
|
type: "button",
|
|
@@ -3415,14 +3765,14 @@ function TwoFactorManager({
|
|
|
3415
3765
|
}
|
|
3416
3766
|
|
|
3417
3767
|
// src/ForgotPassword.tsx
|
|
3418
|
-
var
|
|
3419
|
-
var
|
|
3768
|
+
var import_react17 = require("react");
|
|
3769
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3420
3770
|
function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
3421
3771
|
const { client } = useBase316();
|
|
3422
|
-
const [email, setEmail] = (0,
|
|
3423
|
-
const [sent, setSent] = (0,
|
|
3424
|
-
const [busy, setBusy] = (0,
|
|
3425
|
-
const [error, setError] = (0,
|
|
3772
|
+
const [email, setEmail] = (0, import_react17.useState)("");
|
|
3773
|
+
const [sent, setSent] = (0, import_react17.useState)(false);
|
|
3774
|
+
const [busy, setBusy] = (0, import_react17.useState)(false);
|
|
3775
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
3426
3776
|
async function submit(event) {
|
|
3427
3777
|
event.preventDefault();
|
|
3428
3778
|
setBusy(true);
|
|
@@ -3438,22 +3788,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3438
3788
|
}
|
|
3439
3789
|
}
|
|
3440
3790
|
if (sent) {
|
|
3441
|
-
return /* @__PURE__ */ (0,
|
|
3442
|
-
/* @__PURE__ */ (0,
|
|
3443
|
-
/* @__PURE__ */ (0,
|
|
3791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
3792
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
|
|
3793
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { className: "b316-muted", children: [
|
|
3444
3794
|
"If there is an account for ",
|
|
3445
3795
|
email.trim(),
|
|
3446
3796
|
", a link to set a new password is on its way."
|
|
3447
3797
|
] }),
|
|
3448
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3798
|
+
signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3449
3799
|
] });
|
|
3450
3800
|
}
|
|
3451
|
-
return /* @__PURE__ */ (0,
|
|
3452
|
-
/* @__PURE__ */ (0,
|
|
3453
|
-
error ? /* @__PURE__ */ (0,
|
|
3454
|
-
/* @__PURE__ */ (0,
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
3801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3802
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
|
|
3803
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3804
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-field", children: [
|
|
3805
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
|
|
3806
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3457
3807
|
"input",
|
|
3458
3808
|
{
|
|
3459
3809
|
id: "b316-forgot-email",
|
|
@@ -3466,14 +3816,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3466
3816
|
}
|
|
3467
3817
|
)
|
|
3468
3818
|
] }),
|
|
3469
|
-
/* @__PURE__ */ (0,
|
|
3470
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3819
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
|
|
3820
|
+
signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3471
3821
|
] });
|
|
3472
3822
|
}
|
|
3473
3823
|
|
|
3474
3824
|
// src/ResetPassword.tsx
|
|
3475
|
-
var
|
|
3476
|
-
var
|
|
3825
|
+
var import_react18 = require("react");
|
|
3826
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3477
3827
|
function ResetPassword({
|
|
3478
3828
|
token: supplied,
|
|
3479
3829
|
onReset,
|
|
@@ -3482,13 +3832,13 @@ function ResetPassword({
|
|
|
3482
3832
|
style
|
|
3483
3833
|
}) {
|
|
3484
3834
|
const { client } = useBase316();
|
|
3485
|
-
const [token, setToken] = (0,
|
|
3486
|
-
const [password, setPassword] = (0,
|
|
3487
|
-
const [confirmation, setConfirmation] = (0,
|
|
3488
|
-
const [done, setDone] = (0,
|
|
3489
|
-
const [busy, setBusy] = (0,
|
|
3490
|
-
const [error, setError] = (0,
|
|
3491
|
-
(0,
|
|
3835
|
+
const [token, setToken] = (0, import_react18.useState)(supplied ?? null);
|
|
3836
|
+
const [password, setPassword] = (0, import_react18.useState)("");
|
|
3837
|
+
const [confirmation, setConfirmation] = (0, import_react18.useState)("");
|
|
3838
|
+
const [done, setDone] = (0, import_react18.useState)(false);
|
|
3839
|
+
const [busy, setBusy] = (0, import_react18.useState)(false);
|
|
3840
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
3841
|
+
(0, import_react18.useEffect)(() => {
|
|
3492
3842
|
if (supplied || typeof window === "undefined") {
|
|
3493
3843
|
return;
|
|
3494
3844
|
}
|
|
@@ -3523,24 +3873,24 @@ function ResetPassword({
|
|
|
3523
3873
|
}
|
|
3524
3874
|
}
|
|
3525
3875
|
if (done) {
|
|
3526
|
-
return /* @__PURE__ */ (0,
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3528
|
-
/* @__PURE__ */ (0,
|
|
3529
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
3877
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
|
|
3878
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
|
|
3879
|
+
signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
|
|
3530
3880
|
] });
|
|
3531
3881
|
}
|
|
3532
3882
|
if (!token) {
|
|
3533
|
-
return /* @__PURE__ */ (0,
|
|
3534
|
-
/* @__PURE__ */ (0,
|
|
3535
|
-
/* @__PURE__ */ (0,
|
|
3883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
3884
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
|
|
3885
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
|
|
3536
3886
|
] });
|
|
3537
3887
|
}
|
|
3538
|
-
return /* @__PURE__ */ (0,
|
|
3539
|
-
/* @__PURE__ */ (0,
|
|
3540
|
-
error ? /* @__PURE__ */ (0,
|
|
3541
|
-
/* @__PURE__ */ (0,
|
|
3542
|
-
/* @__PURE__ */ (0,
|
|
3543
|
-
/* @__PURE__ */ (0,
|
|
3888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
|
|
3890
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3891
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
|
|
3892
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
|
|
3893
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3544
3894
|
"input",
|
|
3545
3895
|
{
|
|
3546
3896
|
id: "b316-reset-password",
|
|
@@ -3553,9 +3903,9 @@ function ResetPassword({
|
|
|
3553
3903
|
}
|
|
3554
3904
|
)
|
|
3555
3905
|
] }),
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3558
|
-
/* @__PURE__ */ (0,
|
|
3906
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
|
|
3907
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
|
|
3908
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3559
3909
|
"input",
|
|
3560
3910
|
{
|
|
3561
3911
|
id: "b316-reset-confirm",
|
|
@@ -3568,13 +3918,13 @@ function ResetPassword({
|
|
|
3568
3918
|
}
|
|
3569
3919
|
)
|
|
3570
3920
|
] }),
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
3921
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
|
|
3572
3922
|
] });
|
|
3573
3923
|
}
|
|
3574
3924
|
|
|
3575
3925
|
// src/VerifyEmail.tsx
|
|
3576
|
-
var
|
|
3577
|
-
var
|
|
3926
|
+
var import_react19 = require("react");
|
|
3927
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3578
3928
|
function VerifyEmail({
|
|
3579
3929
|
token: supplied,
|
|
3580
3930
|
onVerified,
|
|
@@ -3583,9 +3933,9 @@ function VerifyEmail({
|
|
|
3583
3933
|
style
|
|
3584
3934
|
}) {
|
|
3585
3935
|
const { client } = useBase316();
|
|
3586
|
-
const [state, setState] = (0,
|
|
3587
|
-
const spent = (0,
|
|
3588
|
-
(0,
|
|
3936
|
+
const [state, setState] = (0, import_react19.useState)("waiting");
|
|
3937
|
+
const spent = (0, import_react19.useRef)(false);
|
|
3938
|
+
(0, import_react19.useEffect)(() => {
|
|
3589
3939
|
if (spent.current) {
|
|
3590
3940
|
return;
|
|
3591
3941
|
}
|
|
@@ -3611,22 +3961,22 @@ function VerifyEmail({
|
|
|
3611
3961
|
setState("failed");
|
|
3612
3962
|
});
|
|
3613
3963
|
}, [client, supplied, onVerified]);
|
|
3614
|
-
return /* @__PURE__ */ (0,
|
|
3615
|
-
/* @__PURE__ */ (0,
|
|
3616
|
-
/* @__PURE__ */ (0,
|
|
3617
|
-
continueUrl ? /* @__PURE__ */ (0,
|
|
3618
|
-
] }) : state === "failed" ? /* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3621
|
-
] }) : state === "missing" ? /* @__PURE__ */ (0,
|
|
3622
|
-
/* @__PURE__ */ (0,
|
|
3623
|
-
/* @__PURE__ */ (0,
|
|
3624
|
-
] }) : /* @__PURE__ */ (0,
|
|
3964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3965
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
|
|
3966
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
|
|
3967
|
+
continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
|
|
3968
|
+
] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3969
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
|
|
3970
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
|
|
3971
|
+
] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3972
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
|
|
3973
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
|
|
3974
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
|
|
3625
3975
|
}
|
|
3626
3976
|
|
|
3627
3977
|
// src/TeamMembers.tsx
|
|
3628
|
-
var
|
|
3629
|
-
var
|
|
3978
|
+
var import_react20 = require("react");
|
|
3979
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3630
3980
|
function TeamMembers({
|
|
3631
3981
|
organizationId,
|
|
3632
3982
|
onInvited,
|
|
@@ -3636,16 +3986,16 @@ function TeamMembers({
|
|
|
3636
3986
|
style
|
|
3637
3987
|
}) {
|
|
3638
3988
|
const { client, token, session } = useBase316();
|
|
3639
|
-
const [teams, setTeams] = (0,
|
|
3640
|
-
const [members, setMembers] = (0,
|
|
3641
|
-
const [invitations, setInvitations] = (0,
|
|
3642
|
-
const [email, setEmail] = (0,
|
|
3643
|
-
const [busy, setBusy] = (0,
|
|
3644
|
-
const [error, setError] = (0,
|
|
3645
|
-
const [copied, setCopied] = (0,
|
|
3989
|
+
const [teams, setTeams] = (0, import_react20.useState)(null);
|
|
3990
|
+
const [members, setMembers] = (0, import_react20.useState)(null);
|
|
3991
|
+
const [invitations, setInvitations] = (0, import_react20.useState)(null);
|
|
3992
|
+
const [email, setEmail] = (0, import_react20.useState)("");
|
|
3993
|
+
const [busy, setBusy] = (0, import_react20.useState)(false);
|
|
3994
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
3995
|
+
const [copied, setCopied] = (0, import_react20.useState)(null);
|
|
3646
3996
|
const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
|
|
3647
3997
|
const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
|
|
3648
|
-
const load = (0,
|
|
3998
|
+
const load = (0, import_react20.useCallback)(() => {
|
|
3649
3999
|
if (!token) {
|
|
3650
4000
|
return;
|
|
3651
4001
|
}
|
|
@@ -3653,8 +4003,8 @@ function TeamMembers({
|
|
|
3653
4003
|
(cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
|
|
3654
4004
|
);
|
|
3655
4005
|
}, [client, token]);
|
|
3656
|
-
(0,
|
|
3657
|
-
(0,
|
|
4006
|
+
(0, import_react20.useEffect)(load, [load]);
|
|
4007
|
+
(0, import_react20.useEffect)(() => {
|
|
3658
4008
|
if (!token || !chosen) {
|
|
3659
4009
|
return;
|
|
3660
4010
|
}
|
|
@@ -3685,10 +4035,10 @@ function TeamMembers({
|
|
|
3685
4035
|
return null;
|
|
3686
4036
|
}
|
|
3687
4037
|
if (!teams) {
|
|
3688
|
-
return /* @__PURE__ */ (0,
|
|
4038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
|
|
3689
4039
|
}
|
|
3690
4040
|
if (!chosen) {
|
|
3691
|
-
return /* @__PURE__ */ (0,
|
|
4041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
|
|
3692
4042
|
}
|
|
3693
4043
|
const canManage = invitations !== null;
|
|
3694
4044
|
async function invite(event) {
|
|
@@ -3738,30 +4088,30 @@ function TeamMembers({
|
|
|
3738
4088
|
setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
|
|
3739
4089
|
}
|
|
3740
4090
|
}
|
|
3741
|
-
return /* @__PURE__ */ (0,
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
4091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
|
|
4092
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
|
|
3743
4093
|
team?.inherited ? (
|
|
3744
4094
|
// Not a member of this team, so not in the list below and with nothing
|
|
3745
4095
|
// to leave: access comes from the team that manages it, and ends there.
|
|
3746
|
-
/* @__PURE__ */ (0,
|
|
4096
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
|
|
3747
4097
|
"You have access through",
|
|
3748
4098
|
" ",
|
|
3749
4099
|
teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
|
|
3750
4100
|
"."
|
|
3751
4101
|
] })
|
|
3752
4102
|
) : null,
|
|
3753
|
-
error ? /* @__PURE__ */ (0,
|
|
3754
|
-
/* @__PURE__ */ (0,
|
|
3755
|
-
/* @__PURE__ */ (0,
|
|
3756
|
-
/* @__PURE__ */ (0,
|
|
3757
|
-
/* @__PURE__ */ (0,
|
|
4103
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
4104
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
|
|
4105
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
4106
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
|
|
4107
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
|
|
3758
4108
|
member.user.email,
|
|
3759
4109
|
member.user.id === session?.userId ? " \xB7 you" : ""
|
|
3760
4110
|
] })
|
|
3761
4111
|
] }),
|
|
3762
|
-
/* @__PURE__ */ (0,
|
|
3763
|
-
/* @__PURE__ */ (0,
|
|
3764
|
-
canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0,
|
|
4112
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-member-side", children: [
|
|
4113
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "b316-chip", children: member.role.name }),
|
|
4114
|
+
canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3765
4115
|
ConfirmButton,
|
|
3766
4116
|
{
|
|
3767
4117
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3773,19 +4123,19 @@ function TeamMembers({
|
|
|
3773
4123
|
) : null
|
|
3774
4124
|
] })
|
|
3775
4125
|
] }, member.id)) }),
|
|
3776
|
-
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
3777
|
-
/* @__PURE__ */ (0,
|
|
3778
|
-
/* @__PURE__ */ (0,
|
|
3779
|
-
/* @__PURE__ */ (0,
|
|
3780
|
-
/* @__PURE__ */ (0,
|
|
3781
|
-
/* @__PURE__ */ (0,
|
|
4126
|
+
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4127
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
|
|
4128
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
|
|
4129
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
|
|
4130
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: invitation.email }),
|
|
4131
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
|
|
3782
4132
|
invitation.role.name,
|
|
3783
4133
|
" \xB7 expires",
|
|
3784
4134
|
" ",
|
|
3785
4135
|
new Date(invitation.expiresAt).toLocaleDateString()
|
|
3786
4136
|
] })
|
|
3787
4137
|
] }),
|
|
3788
|
-
/* @__PURE__ */ (0,
|
|
4138
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3789
4139
|
"button",
|
|
3790
4140
|
{
|
|
3791
4141
|
type: "button",
|
|
@@ -3796,10 +4146,10 @@ function TeamMembers({
|
|
|
3796
4146
|
)
|
|
3797
4147
|
] }, invitation.id)) })
|
|
3798
4148
|
] }) : null,
|
|
3799
|
-
canManage ? /* @__PURE__ */ (0,
|
|
3800
|
-
/* @__PURE__ */ (0,
|
|
3801
|
-
/* @__PURE__ */ (0,
|
|
3802
|
-
/* @__PURE__ */ (0,
|
|
4149
|
+
canManage ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
|
|
4150
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
|
|
4151
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-invite-row", children: [
|
|
4152
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3803
4153
|
"input",
|
|
3804
4154
|
{
|
|
3805
4155
|
id: "b316-invite-email",
|
|
@@ -3811,19 +4161,19 @@ function TeamMembers({
|
|
|
3811
4161
|
onChange: (event) => setEmail(event.target.value)
|
|
3812
4162
|
}
|
|
3813
4163
|
),
|
|
3814
|
-
/* @__PURE__ */ (0,
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
|
|
3815
4165
|
] })
|
|
3816
4166
|
] }) : null,
|
|
3817
|
-
copied ? /* @__PURE__ */ (0,
|
|
3818
|
-
/* @__PURE__ */ (0,
|
|
3819
|
-
/* @__PURE__ */ (0,
|
|
4167
|
+
copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-link", children: [
|
|
4168
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
|
|
4169
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("code", { children: copied })
|
|
3820
4170
|
] }) : null
|
|
3821
4171
|
] });
|
|
3822
4172
|
}
|
|
3823
4173
|
|
|
3824
4174
|
// src/AcceptInvitation.tsx
|
|
3825
|
-
var
|
|
3826
|
-
var
|
|
4175
|
+
var import_react21 = require("react");
|
|
4176
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3827
4177
|
function signUpUrlWithInvitation(url, token) {
|
|
3828
4178
|
const [beforeHash, ...hash] = url.split("#");
|
|
3829
4179
|
const base = beforeHash ?? "";
|
|
@@ -3842,18 +4192,18 @@ function AcceptInvitation({
|
|
|
3842
4192
|
style
|
|
3843
4193
|
}) {
|
|
3844
4194
|
const { client, token: session, session: user } = useBase316();
|
|
3845
|
-
const [invitationToken, setInvitationToken] = (0,
|
|
3846
|
-
const [preview, setPreview] = (0,
|
|
3847
|
-
const [state, setState] = (0,
|
|
3848
|
-
const [error, setError] = (0,
|
|
3849
|
-
const [busy, setBusy] = (0,
|
|
3850
|
-
(0,
|
|
4195
|
+
const [invitationToken, setInvitationToken] = (0, import_react21.useState)(supplied ?? null);
|
|
4196
|
+
const [preview, setPreview] = (0, import_react21.useState)(null);
|
|
4197
|
+
const [state, setState] = (0, import_react21.useState)("loading");
|
|
4198
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
4199
|
+
const [busy, setBusy] = (0, import_react21.useState)(false);
|
|
4200
|
+
(0, import_react21.useEffect)(() => {
|
|
3851
4201
|
if (supplied || typeof window === "undefined") {
|
|
3852
4202
|
return;
|
|
3853
4203
|
}
|
|
3854
4204
|
setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
|
|
3855
4205
|
}, [supplied]);
|
|
3856
|
-
(0,
|
|
4206
|
+
(0, import_react21.useEffect)(() => {
|
|
3857
4207
|
if (!invitationToken) {
|
|
3858
4208
|
setState(supplied === void 0 ? "loading" : "invalid");
|
|
3859
4209
|
return;
|
|
@@ -3890,42 +4240,42 @@ function AcceptInvitation({
|
|
|
3890
4240
|
}
|
|
3891
4241
|
}
|
|
3892
4242
|
if (state === "loading") {
|
|
3893
|
-
return /* @__PURE__ */ (0,
|
|
4243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
3894
4244
|
}
|
|
3895
4245
|
if (state === "invalid") {
|
|
3896
|
-
return /* @__PURE__ */ (0,
|
|
3897
|
-
/* @__PURE__ */ (0,
|
|
3898
|
-
/* @__PURE__ */ (0,
|
|
4246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
4247
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
|
|
4248
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
|
|
3899
4249
|
] });
|
|
3900
4250
|
}
|
|
3901
4251
|
if (state === "accepted") {
|
|
3902
|
-
return /* @__PURE__ */ (0,
|
|
4252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
|
|
3903
4253
|
"You have joined ",
|
|
3904
4254
|
preview?.organizationName
|
|
3905
4255
|
] }) });
|
|
3906
4256
|
}
|
|
3907
4257
|
const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
|
|
3908
|
-
return /* @__PURE__ */ (0,
|
|
3909
|
-
/* @__PURE__ */ (0,
|
|
4258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
|
|
4259
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
|
|
3910
4260
|
"Join ",
|
|
3911
4261
|
preview?.organizationName
|
|
3912
4262
|
] }),
|
|
3913
|
-
/* @__PURE__ */ (0,
|
|
4263
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "b316-muted", children: [
|
|
3914
4264
|
"Invited as ",
|
|
3915
4265
|
preview?.email,
|
|
3916
4266
|
" \xB7 ",
|
|
3917
4267
|
preview?.roleName
|
|
3918
4268
|
] }),
|
|
3919
|
-
error ? /* @__PURE__ */ (0,
|
|
3920
|
-
!session ? /* @__PURE__ */ (0,
|
|
3921
|
-
/* @__PURE__ */ (0,
|
|
4269
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
4270
|
+
!session ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
4271
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
|
|
3922
4272
|
"Sign in as ",
|
|
3923
4273
|
preview?.email,
|
|
3924
4274
|
" to accept."
|
|
3925
4275
|
] }),
|
|
3926
|
-
/* @__PURE__ */ (0,
|
|
3927
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3928
|
-
signUpUrl ? /* @__PURE__ */ (0,
|
|
4276
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-invitation-actions", children: [
|
|
4277
|
+
signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
|
|
4278
|
+
signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3929
4279
|
"a",
|
|
3930
4280
|
{
|
|
3931
4281
|
className: "b316-button-link",
|
|
@@ -3938,20 +4288,20 @@ function AcceptInvitation({
|
|
|
3938
4288
|
// Said before they press anything. The server refuses this, but
|
|
3939
4289
|
// finding out after a click reads as a broken invitation rather than
|
|
3940
4290
|
// as being signed in as the wrong person.
|
|
3941
|
-
/* @__PURE__ */ (0,
|
|
4291
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
|
|
3942
4292
|
"You are signed in as ",
|
|
3943
4293
|
user?.user.email,
|
|
3944
4294
|
". This invitation was sent to ",
|
|
3945
4295
|
preview?.email,
|
|
3946
4296
|
" \u2014 sign in as that address to accept it."
|
|
3947
4297
|
] })
|
|
3948
|
-
) : /* @__PURE__ */ (0,
|
|
4298
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
|
|
3949
4299
|
] });
|
|
3950
4300
|
}
|
|
3951
4301
|
|
|
3952
4302
|
// src/PayInvoice.tsx
|
|
3953
|
-
var
|
|
3954
|
-
var
|
|
4303
|
+
var import_react22 = require("react");
|
|
4304
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3955
4305
|
var STRIPE_SRC = "https://js.stripe.com/v3/";
|
|
3956
4306
|
function loadStripeScript() {
|
|
3957
4307
|
if (typeof window === "undefined") {
|
|
@@ -3983,14 +4333,14 @@ function PayInvoice({
|
|
|
3983
4333
|
style
|
|
3984
4334
|
}) {
|
|
3985
4335
|
const { client } = useBase316();
|
|
3986
|
-
const mountRef = (0,
|
|
3987
|
-
const stripeRef = (0,
|
|
3988
|
-
const elementsRef = (0,
|
|
3989
|
-
const [ready, setReady] = (0,
|
|
3990
|
-
const [paying, setPaying] = (0,
|
|
3991
|
-
const [done, setDone] = (0,
|
|
3992
|
-
const [error, setError] = (0,
|
|
3993
|
-
(0,
|
|
4336
|
+
const mountRef = (0, import_react22.useRef)(null);
|
|
4337
|
+
const stripeRef = (0, import_react22.useRef)(null);
|
|
4338
|
+
const elementsRef = (0, import_react22.useRef)(null);
|
|
4339
|
+
const [ready, setReady] = (0, import_react22.useState)(false);
|
|
4340
|
+
const [paying, setPaying] = (0, import_react22.useState)(false);
|
|
4341
|
+
const [done, setDone] = (0, import_react22.useState)(false);
|
|
4342
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
4343
|
+
(0, import_react22.useEffect)(() => {
|
|
3994
4344
|
let cancelled = false;
|
|
3995
4345
|
async function start() {
|
|
3996
4346
|
const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
|
|
@@ -4043,17 +4393,17 @@ function PayInvoice({
|
|
|
4043
4393
|
onPaid?.();
|
|
4044
4394
|
};
|
|
4045
4395
|
if (done) {
|
|
4046
|
-
return /* @__PURE__ */ (0,
|
|
4396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
|
|
4047
4397
|
}
|
|
4048
|
-
return /* @__PURE__ */ (0,
|
|
4049
|
-
error ? /* @__PURE__ */ (0,
|
|
4050
|
-
/* @__PURE__ */ (0,
|
|
4051
|
-
/* @__PURE__ */ (0,
|
|
4398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
|
|
4399
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
|
|
4400
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
|
|
4401
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
|
|
4052
4402
|
] });
|
|
4053
4403
|
}
|
|
4054
4404
|
|
|
4055
4405
|
// src/usePaymentLink.ts
|
|
4056
|
-
var
|
|
4406
|
+
var import_react23 = require("react");
|
|
4057
4407
|
function usePaymentLink({
|
|
4058
4408
|
token,
|
|
4059
4409
|
environmentId,
|
|
@@ -4061,10 +4411,10 @@ function usePaymentLink({
|
|
|
4061
4411
|
onPaid
|
|
4062
4412
|
}) {
|
|
4063
4413
|
const { client } = useBase316();
|
|
4064
|
-
const [status2, setStatus] = (0,
|
|
4065
|
-
const onPaidRef = (0,
|
|
4414
|
+
const [status2, setStatus] = (0, import_react23.useState)({ state: "loading" });
|
|
4415
|
+
const onPaidRef = (0, import_react23.useRef)(onPaid);
|
|
4066
4416
|
onPaidRef.current = onPaid;
|
|
4067
|
-
(0,
|
|
4417
|
+
(0, import_react23.useEffect)(() => {
|
|
4068
4418
|
let stopped = false;
|
|
4069
4419
|
let timer;
|
|
4070
4420
|
const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
|
|
@@ -4113,23 +4463,23 @@ function usePaymentLink({
|
|
|
4113
4463
|
}
|
|
4114
4464
|
|
|
4115
4465
|
// src/PricingTable.tsx
|
|
4116
|
-
var
|
|
4466
|
+
var import_react25 = require("react");
|
|
4117
4467
|
|
|
4118
4468
|
// src/usePlans.ts
|
|
4119
|
-
var
|
|
4469
|
+
var import_react24 = require("react");
|
|
4120
4470
|
var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
|
|
4121
4471
|
function usePlans(options = {}) {
|
|
4122
4472
|
const { client, token } = useBase316();
|
|
4123
|
-
const [plans, setPlans] = (0,
|
|
4124
|
-
const [error, setError] = (0,
|
|
4125
|
-
const [busyPlanVersionId, setBusy] = (0,
|
|
4126
|
-
const [lastError, setLastError] = (0,
|
|
4127
|
-
const [ownPlanVersionId, setOwnPlanVersionId] = (0,
|
|
4128
|
-
const [managedBy, setManagedBy] = (0,
|
|
4129
|
-
const [reloadCount, setReloadCount] = (0,
|
|
4473
|
+
const [plans, setPlans] = (0, import_react24.useState)(null);
|
|
4474
|
+
const [error, setError] = (0, import_react24.useState)(false);
|
|
4475
|
+
const [busyPlanVersionId, setBusy] = (0, import_react24.useState)(null);
|
|
4476
|
+
const [lastError, setLastError] = (0, import_react24.useState)(null);
|
|
4477
|
+
const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react24.useState)(null);
|
|
4478
|
+
const [managedBy, setManagedBy] = (0, import_react24.useState)(null);
|
|
4479
|
+
const [reloadCount, setReloadCount] = (0, import_react24.useState)(0);
|
|
4130
4480
|
const supplied = options.currentPlanVersionId;
|
|
4131
4481
|
const discover = supplied === void 0;
|
|
4132
|
-
(0,
|
|
4482
|
+
(0, import_react24.useEffect)(() => {
|
|
4133
4483
|
let cancelled = false;
|
|
4134
4484
|
client.billing.plans().then((result) => {
|
|
4135
4485
|
if (!cancelled) {
|
|
@@ -4145,7 +4495,7 @@ function usePlans(options = {}) {
|
|
|
4145
4495
|
cancelled = true;
|
|
4146
4496
|
};
|
|
4147
4497
|
}, [client, reloadCount]);
|
|
4148
|
-
(0,
|
|
4498
|
+
(0, import_react24.useEffect)(() => {
|
|
4149
4499
|
if (!token) {
|
|
4150
4500
|
return;
|
|
4151
4501
|
}
|
|
@@ -4162,11 +4512,11 @@ function usePlans(options = {}) {
|
|
|
4162
4512
|
cancelled = true;
|
|
4163
4513
|
};
|
|
4164
4514
|
}, [client, token, discover, reloadCount]);
|
|
4165
|
-
const reload = (0,
|
|
4515
|
+
const reload = (0, import_react24.useCallback)(() => {
|
|
4166
4516
|
setError(false);
|
|
4167
4517
|
setReloadCount((count) => count + 1);
|
|
4168
4518
|
}, []);
|
|
4169
|
-
const selectPlan = (0,
|
|
4519
|
+
const selectPlan = (0, import_react24.useCallback)(
|
|
4170
4520
|
async (plan) => {
|
|
4171
4521
|
setLastError(null);
|
|
4172
4522
|
if (managedBy) {
|
|
@@ -4234,7 +4584,7 @@ function usePlans(options = {}) {
|
|
|
4234
4584
|
}
|
|
4235
4585
|
|
|
4236
4586
|
// src/PricingTable.tsx
|
|
4237
|
-
var
|
|
4587
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4238
4588
|
function formatAmount(amount, currency) {
|
|
4239
4589
|
if (amount === null) return "Free";
|
|
4240
4590
|
const value = Number(amount);
|
|
@@ -4283,7 +4633,7 @@ function PricingTable({
|
|
|
4283
4633
|
managedBy,
|
|
4284
4634
|
selectPlan
|
|
4285
4635
|
} = usePlans({ currentPlanVersionId });
|
|
4286
|
-
const [scheduled, setScheduled] = (0,
|
|
4636
|
+
const [scheduled, setScheduled] = (0, import_react25.useState)(null);
|
|
4287
4637
|
async function choose(plan) {
|
|
4288
4638
|
if (onSelectPlan) {
|
|
4289
4639
|
await onSelectPlan(plan.planVersionId, plan);
|
|
@@ -4300,50 +4650,50 @@ function PricingTable({
|
|
|
4300
4650
|
}
|
|
4301
4651
|
}
|
|
4302
4652
|
if (error) {
|
|
4303
|
-
return /* @__PURE__ */ (0,
|
|
4653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
|
|
4304
4654
|
}
|
|
4305
4655
|
if (!plans) {
|
|
4306
|
-
return /* @__PURE__ */ (0,
|
|
4656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
|
|
4307
4657
|
}
|
|
4308
4658
|
if (plans.length === 0) {
|
|
4309
|
-
return /* @__PURE__ */ (0,
|
|
4659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
|
|
4310
4660
|
}
|
|
4311
4661
|
const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
|
|
4312
4662
|
const anyDescription = plans.some((plan) => Boolean(plan.description));
|
|
4313
4663
|
const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
|
|
4314
|
-
return /* @__PURE__ */ (0,
|
|
4664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cls("b316-plans", className), style, children: [
|
|
4315
4665
|
managedBy ? (
|
|
4316
4666
|
// A client company's plan comes from the firm that runs it. The table
|
|
4317
4667
|
// still shows what is on offer, with the current plan marked, but
|
|
4318
4668
|
// nothing here can be bought: it would grant this account nothing.
|
|
4319
|
-
/* @__PURE__ */ (0,
|
|
4669
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
|
|
4320
4670
|
"Your plan is provided by ",
|
|
4321
4671
|
managedBy.name ?? "the organization that manages your account",
|
|
4322
4672
|
". Ask them to change it."
|
|
4323
4673
|
] })
|
|
4324
|
-
) : lastError ? /* @__PURE__ */ (0,
|
|
4674
|
+
) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
|
|
4325
4675
|
plans.map((plan) => {
|
|
4326
4676
|
const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
|
|
4327
4677
|
const isCurrent = current === plan.planVersionId;
|
|
4328
4678
|
const featured = featuredPlanKey === plan.key;
|
|
4329
|
-
return /* @__PURE__ */ (0,
|
|
4679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
4330
4680
|
"div",
|
|
4331
4681
|
{
|
|
4332
4682
|
className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
|
|
4333
4683
|
children: [
|
|
4334
|
-
/* @__PURE__ */ (0,
|
|
4335
|
-
anyFeatured ? /* @__PURE__ */ (0,
|
|
4336
|
-
/* @__PURE__ */ (0,
|
|
4337
|
-
anyDescription ? /* @__PURE__ */ (0,
|
|
4684
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-head", children: [
|
|
4685
|
+
anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
|
|
4686
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-name", children: plan.name }),
|
|
4687
|
+
anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
|
|
4338
4688
|
] }),
|
|
4339
|
-
/* @__PURE__ */ (0,
|
|
4340
|
-
/* @__PURE__ */ (0,
|
|
4341
|
-
/* @__PURE__ */ (0,
|
|
4342
|
-
anyTrial ? /* @__PURE__ */ (0,
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-pricing", children: [
|
|
4690
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
|
|
4691
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
|
|
4692
|
+
anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
|
|
4343
4693
|
] }),
|
|
4344
|
-
/* @__PURE__ */ (0,
|
|
4345
|
-
/* @__PURE__ */ (0,
|
|
4346
|
-
/* @__PURE__ */ (0,
|
|
4694
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { className: "b316-plan-feature", children: [
|
|
4695
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: entitlement.featureName }),
|
|
4696
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
|
|
4347
4697
|
// A usage price on the feature makes the limit an
|
|
4348
4698
|
// allowance billed past, not a ceiling — the same
|
|
4349
4699
|
// rule `check()` applies (any non-FLAT price).
|
|
@@ -4352,7 +4702,7 @@ function PricingTable({
|
|
|
4352
4702
|
) ? `${entitlement.limit} included` : entitlement.limit
|
|
4353
4703
|
) })
|
|
4354
4704
|
] }, entitlement.featureId)) }),
|
|
4355
|
-
/* @__PURE__ */ (0,
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4356
4706
|
"button",
|
|
4357
4707
|
{
|
|
4358
4708
|
type: "button",
|
|
@@ -4373,12 +4723,12 @@ function PricingTable({
|
|
|
4373
4723
|
}
|
|
4374
4724
|
|
|
4375
4725
|
// src/DataTable.tsx
|
|
4376
|
-
var
|
|
4377
|
-
var
|
|
4726
|
+
var import_sdk9 = require("@base316/sdk");
|
|
4727
|
+
var import_react29 = require("react");
|
|
4378
4728
|
|
|
4379
4729
|
// src/fields.tsx
|
|
4380
|
-
var
|
|
4381
|
-
var
|
|
4730
|
+
var import_sdk7 = require("@base316/sdk");
|
|
4731
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4382
4732
|
function formatNumber(value, fraction = 0) {
|
|
4383
4733
|
const number = Number(value);
|
|
4384
4734
|
return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
|
|
@@ -4400,10 +4750,10 @@ function formatDuration(value) {
|
|
|
4400
4750
|
}
|
|
4401
4751
|
function FieldCell({ value, field, related }) {
|
|
4402
4752
|
if (field.type === "RELATION") {
|
|
4403
|
-
return related?.title ?? (related?.id ? /* @__PURE__ */ (0,
|
|
4753
|
+
return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
|
|
4404
4754
|
}
|
|
4405
4755
|
if (value === null || value === void 0 || value === "") {
|
|
4406
|
-
return /* @__PURE__ */ (0,
|
|
4756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2014" });
|
|
4407
4757
|
}
|
|
4408
4758
|
switch (field.type) {
|
|
4409
4759
|
case "BOOLEAN":
|
|
@@ -4416,9 +4766,9 @@ function FieldCell({ value, field, related }) {
|
|
|
4416
4766
|
return formatDuration(value);
|
|
4417
4767
|
case "RATING": {
|
|
4418
4768
|
const stars = Math.round(Number(value));
|
|
4419
|
-
return /* @__PURE__ */ (0,
|
|
4769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
|
|
4420
4770
|
"\u2605".repeat(stars),
|
|
4421
|
-
/* @__PURE__ */ (0,
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
|
|
4422
4772
|
] });
|
|
4423
4773
|
}
|
|
4424
4774
|
case "DATE":
|
|
@@ -4426,17 +4776,17 @@ function FieldCell({ value, field, related }) {
|
|
|
4426
4776
|
case "DATETIME":
|
|
4427
4777
|
return new Date(String(value)).toLocaleString();
|
|
4428
4778
|
case "SELECT":
|
|
4429
|
-
return /* @__PURE__ */ (0,
|
|
4779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(value) });
|
|
4430
4780
|
case "MULTISELECT":
|
|
4431
|
-
return /* @__PURE__ */ (0,
|
|
4781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
|
|
4432
4782
|
case "URL":
|
|
4433
|
-
return /* @__PURE__ */ (0,
|
|
4783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
|
|
4434
4784
|
case "EMAIL":
|
|
4435
|
-
return /* @__PURE__ */ (0,
|
|
4785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
|
|
4436
4786
|
case "PHONE":
|
|
4437
|
-
return /* @__PURE__ */ (0,
|
|
4787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
|
|
4438
4788
|
case "ADDRESS":
|
|
4439
|
-
return (0,
|
|
4789
|
+
return (0, import_sdk7.formatAddress)(value);
|
|
4440
4790
|
case "ATTACHMENT": {
|
|
4441
4791
|
const files = Array.isArray(value) ? value : [value];
|
|
4442
4792
|
return `${files.length} file${files.length === 1 ? "" : "s"}`;
|
|
@@ -4446,13 +4796,13 @@ function FieldCell({ value, field, related }) {
|
|
|
4446
4796
|
return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
|
|
4447
4797
|
}
|
|
4448
4798
|
case "JSON":
|
|
4449
|
-
return /* @__PURE__ */ (0,
|
|
4799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
|
|
4450
4800
|
default:
|
|
4451
4801
|
return String(value);
|
|
4452
4802
|
}
|
|
4453
4803
|
}
|
|
4454
4804
|
function FieldInput({ value, field, onChange, error, disabled }) {
|
|
4455
|
-
if ((0,
|
|
4805
|
+
if ((0, import_sdk7.specFor)(field).computed) {
|
|
4456
4806
|
return null;
|
|
4457
4807
|
}
|
|
4458
4808
|
const id = `b316-field-${field.key}`;
|
|
@@ -4467,7 +4817,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4467
4817
|
function control() {
|
|
4468
4818
|
switch (field.type) {
|
|
4469
4819
|
case "LONGTEXT":
|
|
4470
|
-
return /* @__PURE__ */ (0,
|
|
4820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4471
4821
|
"textarea",
|
|
4472
4822
|
{
|
|
4473
4823
|
...common,
|
|
@@ -4477,7 +4827,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4477
4827
|
}
|
|
4478
4828
|
);
|
|
4479
4829
|
case "BOOLEAN":
|
|
4480
|
-
return /* @__PURE__ */ (0,
|
|
4830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4481
4831
|
"input",
|
|
4482
4832
|
{
|
|
4483
4833
|
...common,
|
|
@@ -4488,22 +4838,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4488
4838
|
}
|
|
4489
4839
|
);
|
|
4490
4840
|
case "SELECT":
|
|
4491
|
-
return /* @__PURE__ */ (0,
|
|
4841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
4492
4842
|
"select",
|
|
4493
4843
|
{
|
|
4494
4844
|
...common,
|
|
4495
4845
|
value: value === null || value === void 0 ? "" : String(value),
|
|
4496
4846
|
onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
|
|
4497
4847
|
children: [
|
|
4498
|
-
field.required ? null : /* @__PURE__ */ (0,
|
|
4499
|
-
(field.options ?? []).map((option) => /* @__PURE__ */ (0,
|
|
4848
|
+
field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "", children: "\u2014" }),
|
|
4849
|
+
(field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: option, children: option }, option))
|
|
4500
4850
|
]
|
|
4501
4851
|
}
|
|
4502
4852
|
);
|
|
4503
4853
|
case "MULTISELECT": {
|
|
4504
4854
|
const selected = new Set(Array.isArray(value) ? value.map(String) : []);
|
|
4505
|
-
return /* @__PURE__ */ (0,
|
|
4506
|
-
/* @__PURE__ */ (0,
|
|
4855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-choice", children: [
|
|
4856
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4507
4857
|
"input",
|
|
4508
4858
|
{
|
|
4509
4859
|
type: "checkbox",
|
|
@@ -4526,7 +4876,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4526
4876
|
case "NUMBER":
|
|
4527
4877
|
case "MONEY":
|
|
4528
4878
|
case "PERCENT":
|
|
4529
|
-
return /* @__PURE__ */ (0,
|
|
4879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4530
4880
|
"input",
|
|
4531
4881
|
{
|
|
4532
4882
|
...common,
|
|
@@ -4537,7 +4887,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4537
4887
|
}
|
|
4538
4888
|
);
|
|
4539
4889
|
case "RATING":
|
|
4540
|
-
return /* @__PURE__ */ (0,
|
|
4890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4541
4891
|
"input",
|
|
4542
4892
|
{
|
|
4543
4893
|
...common,
|
|
@@ -4551,8 +4901,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4551
4901
|
);
|
|
4552
4902
|
case "DURATION": {
|
|
4553
4903
|
const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
|
|
4554
|
-
return /* @__PURE__ */ (0,
|
|
4555
|
-
/* @__PURE__ */ (0,
|
|
4904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-suffixed", children: [
|
|
4905
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4556
4906
|
"input",
|
|
4557
4907
|
{
|
|
4558
4908
|
...common,
|
|
@@ -4562,11 +4912,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4562
4912
|
onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
|
|
4563
4913
|
}
|
|
4564
4914
|
),
|
|
4565
|
-
/* @__PURE__ */ (0,
|
|
4915
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "minutes" })
|
|
4566
4916
|
] });
|
|
4567
4917
|
}
|
|
4568
4918
|
case "DATE":
|
|
4569
|
-
return /* @__PURE__ */ (0,
|
|
4919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4570
4920
|
"input",
|
|
4571
4921
|
{
|
|
4572
4922
|
...common,
|
|
@@ -4576,7 +4926,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4576
4926
|
}
|
|
4577
4927
|
);
|
|
4578
4928
|
case "DATETIME":
|
|
4579
|
-
return /* @__PURE__ */ (0,
|
|
4929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4580
4930
|
"input",
|
|
4581
4931
|
{
|
|
4582
4932
|
...common,
|
|
@@ -4589,7 +4939,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4589
4939
|
);
|
|
4590
4940
|
case "ADDRESS": {
|
|
4591
4941
|
const address = value ?? {};
|
|
4592
|
-
const part = (key, label) => /* @__PURE__ */ (0,
|
|
4942
|
+
const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4593
4943
|
"input",
|
|
4594
4944
|
{
|
|
4595
4945
|
className: "b316-input",
|
|
@@ -4601,7 +4951,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4601
4951
|
},
|
|
4602
4952
|
key
|
|
4603
4953
|
);
|
|
4604
|
-
return /* @__PURE__ */ (0,
|
|
4954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-address", children: [
|
|
4605
4955
|
part("line1", "Address line 1"),
|
|
4606
4956
|
part("line2", "Address line 2"),
|
|
4607
4957
|
part("city", "City"),
|
|
@@ -4611,7 +4961,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4611
4961
|
] });
|
|
4612
4962
|
}
|
|
4613
4963
|
case "EMAIL":
|
|
4614
|
-
return /* @__PURE__ */ (0,
|
|
4964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4615
4965
|
"input",
|
|
4616
4966
|
{
|
|
4617
4967
|
...common,
|
|
@@ -4621,7 +4971,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4621
4971
|
}
|
|
4622
4972
|
);
|
|
4623
4973
|
case "URL":
|
|
4624
|
-
return /* @__PURE__ */ (0,
|
|
4974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4625
4975
|
"input",
|
|
4626
4976
|
{
|
|
4627
4977
|
...common,
|
|
@@ -4631,7 +4981,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4631
4981
|
}
|
|
4632
4982
|
);
|
|
4633
4983
|
case "PHONE":
|
|
4634
|
-
return /* @__PURE__ */ (0,
|
|
4984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4635
4985
|
"input",
|
|
4636
4986
|
{
|
|
4637
4987
|
...common,
|
|
@@ -4641,7 +4991,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4641
4991
|
}
|
|
4642
4992
|
);
|
|
4643
4993
|
default:
|
|
4644
|
-
return /* @__PURE__ */ (0,
|
|
4994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4645
4995
|
"input",
|
|
4646
4996
|
{
|
|
4647
4997
|
...common,
|
|
@@ -4652,24 +5002,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4652
5002
|
);
|
|
4653
5003
|
}
|
|
4654
5004
|
}
|
|
4655
|
-
return /* @__PURE__ */ (0,
|
|
4656
|
-
/* @__PURE__ */ (0,
|
|
5005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-field", children: [
|
|
5006
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
|
|
4657
5007
|
field.label,
|
|
4658
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5008
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4659
5009
|
] }),
|
|
4660
5010
|
control(),
|
|
4661
|
-
field.description ? /* @__PURE__ */ (0,
|
|
4662
|
-
error ? /* @__PURE__ */ (0,
|
|
5011
|
+
field.description ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-hint", children: field.description }) : null,
|
|
5012
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
|
|
4663
5013
|
] });
|
|
4664
5014
|
}
|
|
4665
5015
|
|
|
4666
5016
|
// src/RecordForm.tsx
|
|
4667
|
-
var
|
|
4668
|
-
var
|
|
5017
|
+
var import_sdk8 = require("@base316/sdk");
|
|
5018
|
+
var import_react28 = require("react");
|
|
4669
5019
|
|
|
4670
5020
|
// src/RelationPicker.tsx
|
|
4671
|
-
var
|
|
4672
|
-
var
|
|
5021
|
+
var import_react26 = require("react");
|
|
5022
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
4673
5023
|
function RelationPicker({
|
|
4674
5024
|
field,
|
|
4675
5025
|
value,
|
|
@@ -4679,13 +5029,13 @@ function RelationPicker({
|
|
|
4679
5029
|
tenant
|
|
4680
5030
|
}) {
|
|
4681
5031
|
const { client, token } = useBase316();
|
|
4682
|
-
const [query, setQuery] = (0,
|
|
4683
|
-
const [results, setResults] = (0,
|
|
4684
|
-
const [chosenTitle, setChosenTitle] = (0,
|
|
4685
|
-
const [open, setOpen] = (0,
|
|
5032
|
+
const [query, setQuery] = (0, import_react26.useState)("");
|
|
5033
|
+
const [results, setResults] = (0, import_react26.useState)([]);
|
|
5034
|
+
const [chosenTitle, setChosenTitle] = (0, import_react26.useState)(null);
|
|
5035
|
+
const [open, setOpen] = (0, import_react26.useState)(false);
|
|
4686
5036
|
const id = `b316-field-${field.key}`;
|
|
4687
|
-
const box = (0,
|
|
4688
|
-
(0,
|
|
5037
|
+
const box = (0, import_react26.useRef)(null);
|
|
5038
|
+
(0, import_react26.useEffect)(() => {
|
|
4689
5039
|
if (!token || !value || !field.relationTo) {
|
|
4690
5040
|
setChosenTitle(null);
|
|
4691
5041
|
return;
|
|
@@ -4700,7 +5050,7 @@ function RelationPicker({
|
|
|
4700
5050
|
cancelled = true;
|
|
4701
5051
|
};
|
|
4702
5052
|
}, [client, token, value, field.relationTo, tenant]);
|
|
4703
|
-
(0,
|
|
5053
|
+
(0, import_react26.useEffect)(() => {
|
|
4704
5054
|
if (!token || !field.relationTo || !open) {
|
|
4705
5055
|
return;
|
|
4706
5056
|
}
|
|
@@ -4726,7 +5076,7 @@ function RelationPicker({
|
|
|
4726
5076
|
clearTimeout(timer);
|
|
4727
5077
|
};
|
|
4728
5078
|
}, [client, token, field.relationTo, query, open, tenant]);
|
|
4729
|
-
(0,
|
|
5079
|
+
(0, import_react26.useEffect)(() => {
|
|
4730
5080
|
if (!open || typeof document === "undefined") {
|
|
4731
5081
|
return;
|
|
4732
5082
|
}
|
|
@@ -4740,14 +5090,14 @@ function RelationPicker({
|
|
|
4740
5090
|
document.removeEventListener("mousedown", onDocumentClick);
|
|
4741
5091
|
};
|
|
4742
5092
|
}, [open]);
|
|
4743
|
-
return /* @__PURE__ */ (0,
|
|
4744
|
-
/* @__PURE__ */ (0,
|
|
5093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-field", ref: box, children: [
|
|
5094
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
|
|
4745
5095
|
field.label,
|
|
4746
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5096
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4747
5097
|
] }),
|
|
4748
|
-
value && !open ? /* @__PURE__ */ (0,
|
|
4749
|
-
/* @__PURE__ */ (0,
|
|
4750
|
-
disabled ? null : /* @__PURE__ */ (0,
|
|
5098
|
+
value && !open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-relation-chosen", children: [
|
|
5099
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: chosenTitle ?? value }),
|
|
5100
|
+
disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4751
5101
|
"button",
|
|
4752
5102
|
{
|
|
4753
5103
|
type: "button",
|
|
@@ -4759,7 +5109,7 @@ function RelationPicker({
|
|
|
4759
5109
|
children: "Change"
|
|
4760
5110
|
}
|
|
4761
5111
|
),
|
|
4762
|
-
disabled || field.required ? null : /* @__PURE__ */ (0,
|
|
5112
|
+
disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4763
5113
|
"button",
|
|
4764
5114
|
{
|
|
4765
5115
|
type: "button",
|
|
@@ -4769,8 +5119,8 @@ function RelationPicker({
|
|
|
4769
5119
|
children: "Clear"
|
|
4770
5120
|
}
|
|
4771
5121
|
)
|
|
4772
|
-
] }) : /* @__PURE__ */ (0,
|
|
4773
|
-
/* @__PURE__ */ (0,
|
|
5122
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5123
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4774
5124
|
"input",
|
|
4775
5125
|
{
|
|
4776
5126
|
id,
|
|
@@ -4791,7 +5141,7 @@ function RelationPicker({
|
|
|
4791
5141
|
}
|
|
4792
5142
|
}
|
|
4793
5143
|
),
|
|
4794
|
-
open ? /* @__PURE__ */ (0,
|
|
5144
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4795
5145
|
"button",
|
|
4796
5146
|
{
|
|
4797
5147
|
type: "button",
|
|
@@ -4807,13 +5157,13 @@ function RelationPicker({
|
|
|
4807
5157
|
}
|
|
4808
5158
|
) }, result.id)) }) : null
|
|
4809
5159
|
] }),
|
|
4810
|
-
field.description ? /* @__PURE__ */ (0,
|
|
4811
|
-
error ? /* @__PURE__ */ (0,
|
|
5160
|
+
field.description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-hint", children: field.description }) : null,
|
|
5161
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
|
|
4812
5162
|
] });
|
|
4813
5163
|
}
|
|
4814
5164
|
|
|
4815
5165
|
// src/useCollection.ts
|
|
4816
|
-
var
|
|
5166
|
+
var import_react27 = require("react");
|
|
4817
5167
|
function fieldErrorFrom(cause) {
|
|
4818
5168
|
const param = cause?.param;
|
|
4819
5169
|
const message = cause instanceof Error ? cause.message : "That value was not accepted.";
|
|
@@ -4821,24 +5171,24 @@ function fieldErrorFrom(cause) {
|
|
|
4821
5171
|
}
|
|
4822
5172
|
function useCollection(collection, options = {}) {
|
|
4823
5173
|
const { client, token } = useBase316();
|
|
4824
|
-
const [schema, setSchema] = (0,
|
|
4825
|
-
const [records, setRecords] = (0,
|
|
4826
|
-
const [error, setError] = (0,
|
|
4827
|
-
const [loading, setLoading] = (0,
|
|
4828
|
-
const [total, setTotal] = (0,
|
|
4829
|
-
const [cursor, setCursor] = (0,
|
|
4830
|
-
const [reloadCount, setReloadCount] = (0,
|
|
4831
|
-
const [search, setSearch] = (0,
|
|
4832
|
-
const [filters, setFilters] = (0,
|
|
4833
|
-
const [sort, setSort] = (0,
|
|
5174
|
+
const [schema, setSchema] = (0, import_react27.useState)(null);
|
|
5175
|
+
const [records, setRecords] = (0, import_react27.useState)([]);
|
|
5176
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
5177
|
+
const [loading, setLoading] = (0, import_react27.useState)(true);
|
|
5178
|
+
const [total, setTotal] = (0, import_react27.useState)(0);
|
|
5179
|
+
const [cursor, setCursor] = (0, import_react27.useState)(null);
|
|
5180
|
+
const [reloadCount, setReloadCount] = (0, import_react27.useState)(0);
|
|
5181
|
+
const [search, setSearch] = (0, import_react27.useState)("");
|
|
5182
|
+
const [filters, setFilters] = (0, import_react27.useState)([]);
|
|
5183
|
+
const [sort, setSort] = (0, import_react27.useState)(
|
|
4834
5184
|
options.sort ?? null
|
|
4835
5185
|
);
|
|
4836
|
-
const [fieldErrors, setFieldErrors] = (0,
|
|
4837
|
-
const [saving, setSaving] = (0,
|
|
5186
|
+
const [fieldErrors, setFieldErrors] = (0, import_react27.useState)({});
|
|
5187
|
+
const [saving, setSaving] = (0, import_react27.useState)(false);
|
|
4838
5188
|
const { tenant, limit, recordId } = options;
|
|
4839
5189
|
const fixedFilters = JSON.stringify(options.filters ?? []);
|
|
4840
|
-
const scope = (0,
|
|
4841
|
-
(0,
|
|
5190
|
+
const scope = (0, import_react27.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
|
|
5191
|
+
(0, import_react27.useEffect)(() => {
|
|
4842
5192
|
if (!token) {
|
|
4843
5193
|
return;
|
|
4844
5194
|
}
|
|
@@ -4857,7 +5207,7 @@ function useCollection(collection, options = {}) {
|
|
|
4857
5207
|
cancelled = true;
|
|
4858
5208
|
};
|
|
4859
5209
|
}, [client, token, collection, scope]);
|
|
4860
|
-
(0,
|
|
5210
|
+
(0, import_react27.useEffect)(() => {
|
|
4861
5211
|
if (!token || !schema) {
|
|
4862
5212
|
return;
|
|
4863
5213
|
}
|
|
@@ -4927,10 +5277,10 @@ function useCollection(collection, options = {}) {
|
|
|
4927
5277
|
scope,
|
|
4928
5278
|
reloadCount
|
|
4929
5279
|
]);
|
|
4930
|
-
const reload = (0,
|
|
5280
|
+
const reload = (0, import_react27.useCallback)(() => {
|
|
4931
5281
|
setReloadCount((count) => count + 1);
|
|
4932
5282
|
}, []);
|
|
4933
|
-
const loadMore = (0,
|
|
5283
|
+
const loadMore = (0, import_react27.useCallback)(() => {
|
|
4934
5284
|
if (!token || !cursor) {
|
|
4935
5285
|
return;
|
|
4936
5286
|
}
|
|
@@ -4954,7 +5304,7 @@ function useCollection(collection, options = {}) {
|
|
|
4954
5304
|
setLoading(false);
|
|
4955
5305
|
});
|
|
4956
5306
|
}, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
|
|
4957
|
-
const toggleSort = (0,
|
|
5307
|
+
const toggleSort = (0, import_react27.useCallback)((field) => {
|
|
4958
5308
|
setSort((current) => {
|
|
4959
5309
|
if (current?.field !== field) {
|
|
4960
5310
|
return { field, direction: "asc" };
|
|
@@ -4962,7 +5312,7 @@ function useCollection(collection, options = {}) {
|
|
|
4962
5312
|
return current.direction === "asc" ? { field, direction: "desc" } : null;
|
|
4963
5313
|
});
|
|
4964
5314
|
}, []);
|
|
4965
|
-
const create = (0,
|
|
5315
|
+
const create = (0, import_react27.useCallback)(
|
|
4966
5316
|
async (fields) => {
|
|
4967
5317
|
if (!token) {
|
|
4968
5318
|
return null;
|
|
@@ -4982,7 +5332,7 @@ function useCollection(collection, options = {}) {
|
|
|
4982
5332
|
},
|
|
4983
5333
|
[client, token, collection, scope, reload]
|
|
4984
5334
|
);
|
|
4985
|
-
const update = (0,
|
|
5335
|
+
const update = (0, import_react27.useCallback)(
|
|
4986
5336
|
async (id, fields) => {
|
|
4987
5337
|
if (!token) {
|
|
4988
5338
|
return null;
|
|
@@ -5004,7 +5354,7 @@ function useCollection(collection, options = {}) {
|
|
|
5004
5354
|
},
|
|
5005
5355
|
[client, token, collection, scope]
|
|
5006
5356
|
);
|
|
5007
|
-
const remove = (0,
|
|
5357
|
+
const remove = (0, import_react27.useCallback)(
|
|
5008
5358
|
async (id) => {
|
|
5009
5359
|
if (!token) {
|
|
5010
5360
|
return false;
|
|
@@ -5049,7 +5399,7 @@ function useCollection(collection, options = {}) {
|
|
|
5049
5399
|
}
|
|
5050
5400
|
|
|
5051
5401
|
// src/RecordForm.tsx
|
|
5052
|
-
var
|
|
5402
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5053
5403
|
function RecordForm({
|
|
5054
5404
|
collection,
|
|
5055
5405
|
recordId,
|
|
@@ -5070,22 +5420,22 @@ function RecordForm({
|
|
|
5070
5420
|
recordId
|
|
5071
5421
|
}
|
|
5072
5422
|
);
|
|
5073
|
-
const [values, setValues] = (0,
|
|
5074
|
-
const [loaded, setLoaded] = (0,
|
|
5423
|
+
const [values, setValues] = (0, import_react28.useState)(defaults ?? {});
|
|
5424
|
+
const [loaded, setLoaded] = (0, import_react28.useState)(!recordId);
|
|
5075
5425
|
const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
|
|
5076
|
-
(0,
|
|
5426
|
+
(0, import_react28.useEffect)(() => {
|
|
5077
5427
|
if (existing && !loaded) {
|
|
5078
5428
|
setValues(existing.fields);
|
|
5079
5429
|
setLoaded(true);
|
|
5080
5430
|
}
|
|
5081
5431
|
}, [existing, loaded]);
|
|
5082
5432
|
if (error) {
|
|
5083
|
-
return /* @__PURE__ */ (0,
|
|
5433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5084
5434
|
}
|
|
5085
5435
|
if (!schema || !loaded) {
|
|
5086
|
-
return /* @__PURE__ */ (0,
|
|
5436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5087
5437
|
}
|
|
5088
|
-
const editable = schema.fields.filter((field) => !(0,
|
|
5438
|
+
const editable = schema.fields.filter((field) => !(0, import_sdk8.specFor)(field).computed);
|
|
5089
5439
|
async function submit(event) {
|
|
5090
5440
|
event.preventDefault();
|
|
5091
5441
|
const saved = recordId ? await update(recordId, values) : await create(values);
|
|
@@ -5093,11 +5443,11 @@ function RecordForm({
|
|
|
5093
5443
|
onSaved?.(saved.id);
|
|
5094
5444
|
}
|
|
5095
5445
|
}
|
|
5096
|
-
return /* @__PURE__ */ (0,
|
|
5097
|
-
/* @__PURE__ */ (0,
|
|
5098
|
-
fieldErrors._ ? /* @__PURE__ */ (0,
|
|
5446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
5447
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
|
|
5448
|
+
fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
|
|
5099
5449
|
editable.map(
|
|
5100
|
-
(field) => field.type === "RELATION" ? /* @__PURE__ */ (0,
|
|
5450
|
+
(field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5101
5451
|
RelationPicker,
|
|
5102
5452
|
{
|
|
5103
5453
|
field,
|
|
@@ -5108,7 +5458,7 @@ function RecordForm({
|
|
|
5108
5458
|
onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
|
|
5109
5459
|
},
|
|
5110
5460
|
field.key
|
|
5111
|
-
) : /* @__PURE__ */ (0,
|
|
5461
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5112
5462
|
FieldInput,
|
|
5113
5463
|
{
|
|
5114
5464
|
field,
|
|
@@ -5120,15 +5470,15 @@ function RecordForm({
|
|
|
5120
5470
|
field.key
|
|
5121
5471
|
)
|
|
5122
5472
|
),
|
|
5123
|
-
/* @__PURE__ */ (0,
|
|
5124
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
5125
|
-
/* @__PURE__ */ (0,
|
|
5473
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-form-actions", children: [
|
|
5474
|
+
onCancel ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
|
|
5475
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
|
|
5126
5476
|
] })
|
|
5127
5477
|
] });
|
|
5128
5478
|
}
|
|
5129
5479
|
|
|
5130
5480
|
// src/DataTable.tsx
|
|
5131
|
-
var
|
|
5481
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5132
5482
|
function DataTable({
|
|
5133
5483
|
collection,
|
|
5134
5484
|
columns,
|
|
@@ -5157,25 +5507,25 @@ function DataTable({
|
|
|
5157
5507
|
loadMore,
|
|
5158
5508
|
remove
|
|
5159
5509
|
} = useCollection(collection, options);
|
|
5160
|
-
const [editing, setEditing] = (0,
|
|
5161
|
-
const [removeFailed, setRemoveFailed] = (0,
|
|
5510
|
+
const [editing, setEditing] = (0, import_react29.useState)(null);
|
|
5511
|
+
const [removeFailed, setRemoveFailed] = (0, import_react29.useState)(null);
|
|
5162
5512
|
if (error) {
|
|
5163
|
-
return /* @__PURE__ */ (0,
|
|
5513
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5164
5514
|
}
|
|
5165
5515
|
if (!schema) {
|
|
5166
|
-
return /* @__PURE__ */ (0,
|
|
5516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5167
5517
|
}
|
|
5168
5518
|
const shown = columns ? (
|
|
5169
5519
|
// Ordered by what was asked for, not by the schema: a caller naming
|
|
5170
5520
|
// columns means that order.
|
|
5171
5521
|
columns.map((key) => schema.fields.find((field) => field.key === key)).filter((field) => Boolean(field))
|
|
5172
5522
|
) : schema.fields;
|
|
5173
|
-
const searchable = schema.fields.some((field) => (0,
|
|
5523
|
+
const searchable = schema.fields.some((field) => (0, import_sdk9.specFor)(field).capabilities.searchable);
|
|
5174
5524
|
const writable = canWrite && !readOnly;
|
|
5175
|
-
return /* @__PURE__ */ (0,
|
|
5176
|
-
removeFailed ? /* @__PURE__ */ (0,
|
|
5177
|
-
/* @__PURE__ */ (0,
|
|
5178
|
-
searchable && !hideSearch ? /* @__PURE__ */ (0,
|
|
5525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
|
|
5526
|
+
removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
|
|
5527
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-bar", children: [
|
|
5528
|
+
searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5179
5529
|
"input",
|
|
5180
5530
|
{
|
|
5181
5531
|
type: "search",
|
|
@@ -5185,25 +5535,25 @@ function DataTable({
|
|
|
5185
5535
|
value: search,
|
|
5186
5536
|
onChange: (event) => setSearch(event.target.value)
|
|
5187
5537
|
}
|
|
5188
|
-
) : /* @__PURE__ */ (0,
|
|
5189
|
-
/* @__PURE__ */ (0,
|
|
5190
|
-
/* @__PURE__ */ (0,
|
|
5538
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {}),
|
|
5539
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-actions", children: [
|
|
5540
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "b316-muted", children: [
|
|
5191
5541
|
total,
|
|
5192
5542
|
" ",
|
|
5193
5543
|
total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
|
|
5194
5544
|
] }),
|
|
5195
|
-
writable ? /* @__PURE__ */ (0,
|
|
5545
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
|
|
5196
5546
|
"New ",
|
|
5197
5547
|
schema.name.toLowerCase()
|
|
5198
5548
|
] }) : null
|
|
5199
5549
|
] })
|
|
5200
5550
|
] }),
|
|
5201
|
-
/* @__PURE__ */ (0,
|
|
5202
|
-
/* @__PURE__ */ (0,
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
|
|
5552
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
|
|
5203
5553
|
shown.map((field) => {
|
|
5204
|
-
const sortable = (0,
|
|
5554
|
+
const sortable = (0, import_sdk9.specFor)(field).capabilities.sortable;
|
|
5205
5555
|
const active = sort?.field === field.key;
|
|
5206
|
-
return /* @__PURE__ */ (0,
|
|
5556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5207
5557
|
"button",
|
|
5208
5558
|
{
|
|
5209
5559
|
type: "button",
|
|
@@ -5211,20 +5561,20 @@ function DataTable({
|
|
|
5211
5561
|
onClick: () => toggleSort(field.key),
|
|
5212
5562
|
children: [
|
|
5213
5563
|
field.label,
|
|
5214
|
-
/* @__PURE__ */ (0,
|
|
5564
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
|
|
5215
5565
|
]
|
|
5216
5566
|
}
|
|
5217
5567
|
) : field.label }, field.key);
|
|
5218
5568
|
}),
|
|
5219
|
-
writable ? /* @__PURE__ */ (0,
|
|
5569
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
|
|
5220
5570
|
] }) }),
|
|
5221
|
-
/* @__PURE__ */ (0,
|
|
5571
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5222
5572
|
"tr",
|
|
5223
5573
|
{
|
|
5224
5574
|
className: onSelect ? "b316-row-clickable" : void 0,
|
|
5225
5575
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5226
5576
|
children: [
|
|
5227
|
-
shown.map((field) => /* @__PURE__ */ (0,
|
|
5577
|
+
shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5228
5578
|
FieldCell,
|
|
5229
5579
|
{
|
|
5230
5580
|
value: record.fields[field.key] ?? null,
|
|
@@ -5232,8 +5582,8 @@ function DataTable({
|
|
|
5232
5582
|
related: record.related[field.key]
|
|
5233
5583
|
}
|
|
5234
5584
|
) }, field.key)),
|
|
5235
|
-
writable ? /* @__PURE__ */ (0,
|
|
5236
|
-
/* @__PURE__ */ (0,
|
|
5585
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("td", { className: "b316-table-rowactions", children: [
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5237
5587
|
"button",
|
|
5238
5588
|
{
|
|
5239
5589
|
type: "button",
|
|
@@ -5245,7 +5595,7 @@ function DataTable({
|
|
|
5245
5595
|
children: "Edit"
|
|
5246
5596
|
}
|
|
5247
5597
|
),
|
|
5248
|
-
/* @__PURE__ */ (0,
|
|
5598
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5249
5599
|
ConfirmButton,
|
|
5250
5600
|
{
|
|
5251
5601
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5269,10 +5619,10 @@ function DataTable({
|
|
|
5269
5619
|
record.id
|
|
5270
5620
|
)) })
|
|
5271
5621
|
] }) }),
|
|
5272
|
-
records.length === 0 && !loading ? /* @__PURE__ */ (0,
|
|
5273
|
-
loading ? /* @__PURE__ */ (0,
|
|
5274
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
5275
|
-
editing ? /* @__PURE__ */ (0,
|
|
5622
|
+
records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
|
|
5623
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
|
|
5624
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
|
|
5625
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5276
5626
|
RecordForm,
|
|
5277
5627
|
{
|
|
5278
5628
|
collection,
|
|
@@ -5295,9 +5645,9 @@ function ariaSort(active, direction) {
|
|
|
5295
5645
|
}
|
|
5296
5646
|
|
|
5297
5647
|
// src/Kanban.tsx
|
|
5298
|
-
var
|
|
5299
|
-
var
|
|
5300
|
-
var
|
|
5648
|
+
var import_sdk10 = require("@base316/sdk");
|
|
5649
|
+
var import_react30 = require("react");
|
|
5650
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5301
5651
|
function Kanban({
|
|
5302
5652
|
collection,
|
|
5303
5653
|
groupBy,
|
|
@@ -5314,17 +5664,17 @@ function Kanban({
|
|
|
5314
5664
|
limit: options.limit ?? 100,
|
|
5315
5665
|
...options
|
|
5316
5666
|
});
|
|
5317
|
-
const [dragging, setDragging] = (0,
|
|
5318
|
-
const [over, setOver] = (0,
|
|
5667
|
+
const [dragging, setDragging] = (0, import_react30.useState)(null);
|
|
5668
|
+
const [over, setOver] = (0, import_react30.useState)(null);
|
|
5319
5669
|
if (error) {
|
|
5320
|
-
return /* @__PURE__ */ (0,
|
|
5670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5321
5671
|
}
|
|
5322
5672
|
if (!schema) {
|
|
5323
|
-
return /* @__PURE__ */ (0,
|
|
5673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5324
5674
|
}
|
|
5325
|
-
const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0,
|
|
5326
|
-
if (!field || !(0,
|
|
5327
|
-
return /* @__PURE__ */ (0,
|
|
5675
|
+
const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk10.defaultGroupFieldOf)(schema.fields);
|
|
5676
|
+
if (!field || !(0, import_sdk10.specFor)(field).capabilities.groupable) {
|
|
5677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
|
|
5328
5678
|
}
|
|
5329
5679
|
const columns = columnsFor(field);
|
|
5330
5680
|
const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
|
|
@@ -5332,7 +5682,7 @@ function Kanban({
|
|
|
5332
5682
|
// The grouping field is already the column heading and the title is
|
|
5333
5683
|
// already the card heading, so both would be printed twice on every card.
|
|
5334
5684
|
schema.fields.filter(
|
|
5335
|
-
(candidate) => candidate.key !== field.key && candidate.key !== (0,
|
|
5685
|
+
(candidate) => candidate.key !== field.key && candidate.key !== (0, import_sdk10.titleFieldOf)(schema.fields)?.key
|
|
5336
5686
|
).slice(0, 3)
|
|
5337
5687
|
);
|
|
5338
5688
|
async function move(record, value) {
|
|
@@ -5341,12 +5691,12 @@ function Kanban({
|
|
|
5341
5691
|
}
|
|
5342
5692
|
await update(record.id, { [field.key]: value });
|
|
5343
5693
|
}
|
|
5344
|
-
return /* @__PURE__ */ (0,
|
|
5345
|
-
/* @__PURE__ */ (0,
|
|
5694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
|
|
5695
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
|
|
5346
5696
|
const inColumn = records.filter(
|
|
5347
5697
|
(record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
|
|
5348
5698
|
);
|
|
5349
|
-
return /* @__PURE__ */ (0,
|
|
5699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5350
5700
|
"section",
|
|
5351
5701
|
{
|
|
5352
5702
|
className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
|
|
@@ -5370,12 +5720,12 @@ function Kanban({
|
|
|
5370
5720
|
setDragging(null);
|
|
5371
5721
|
},
|
|
5372
5722
|
children: [
|
|
5373
|
-
/* @__PURE__ */ (0,
|
|
5374
|
-
/* @__PURE__ */ (0,
|
|
5375
|
-
/* @__PURE__ */ (0,
|
|
5723
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("header", { className: "b316-board-head", children: [
|
|
5724
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-board-title", children: column.label }),
|
|
5725
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: inColumn.length })
|
|
5376
5726
|
] }),
|
|
5377
|
-
/* @__PURE__ */ (0,
|
|
5378
|
-
inColumn.map((record) => /* @__PURE__ */ (0,
|
|
5727
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-cards", children: [
|
|
5728
|
+
inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5379
5729
|
"article",
|
|
5380
5730
|
{
|
|
5381
5731
|
className: "b316-board-card",
|
|
@@ -5387,10 +5737,10 @@ function Kanban({
|
|
|
5387
5737
|
},
|
|
5388
5738
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5389
5739
|
children: [
|
|
5390
|
-
/* @__PURE__ */ (0,
|
|
5391
|
-
shown.map((candidate) => /* @__PURE__ */ (0,
|
|
5392
|
-
/* @__PURE__ */ (0,
|
|
5393
|
-
/* @__PURE__ */ (0,
|
|
5740
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
|
|
5741
|
+
shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-card-field", children: [
|
|
5742
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: candidate.label }),
|
|
5743
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5394
5744
|
FieldCell,
|
|
5395
5745
|
{
|
|
5396
5746
|
value: record.fields[candidate.key] ?? null,
|
|
@@ -5403,9 +5753,9 @@ function Kanban({
|
|
|
5403
5753
|
// Dragging is not reachable by keyboard and is awkward on a
|
|
5404
5754
|
// phone. This is the same action by other means, not a
|
|
5405
5755
|
// lesser fallback.
|
|
5406
|
-
/* @__PURE__ */ (0,
|
|
5407
|
-
/* @__PURE__ */ (0,
|
|
5408
|
-
/* @__PURE__ */ (0,
|
|
5756
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "b316-board-move", children: [
|
|
5757
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: "Move to" }),
|
|
5758
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
5409
5759
|
"select",
|
|
5410
5760
|
{
|
|
5411
5761
|
className: "b316-input",
|
|
@@ -5417,7 +5767,7 @@ function Kanban({
|
|
|
5417
5767
|
);
|
|
5418
5768
|
void move(record, chosen?.value ?? null);
|
|
5419
5769
|
},
|
|
5420
|
-
children: columns.map((candidate) => /* @__PURE__ */ (0,
|
|
5770
|
+
children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
|
|
5421
5771
|
}
|
|
5422
5772
|
)
|
|
5423
5773
|
] })
|
|
@@ -5426,14 +5776,14 @@ function Kanban({
|
|
|
5426
5776
|
},
|
|
5427
5777
|
record.id
|
|
5428
5778
|
)),
|
|
5429
|
-
inColumn.length === 0 ? /* @__PURE__ */ (0,
|
|
5779
|
+
inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
|
|
5430
5780
|
] })
|
|
5431
5781
|
]
|
|
5432
5782
|
},
|
|
5433
5783
|
String(column.value)
|
|
5434
5784
|
);
|
|
5435
5785
|
}) }),
|
|
5436
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
5786
|
+
hasMore ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
|
|
5437
5787
|
"Showing ",
|
|
5438
5788
|
records.length,
|
|
5439
5789
|
" of ",
|
|
@@ -5454,9 +5804,9 @@ function columnsFor(field) {
|
|
|
5454
5804
|
}
|
|
5455
5805
|
|
|
5456
5806
|
// src/Chart.tsx
|
|
5457
|
-
var
|
|
5458
|
-
var
|
|
5459
|
-
var
|
|
5807
|
+
var import_sdk11 = require("@base316/sdk");
|
|
5808
|
+
var import_react31 = require("react");
|
|
5809
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5460
5810
|
function Chart({
|
|
5461
5811
|
collection,
|
|
5462
5812
|
x,
|
|
@@ -5475,43 +5825,43 @@ function Chart({
|
|
|
5475
5825
|
limit: options.limit ?? 200,
|
|
5476
5826
|
...options
|
|
5477
5827
|
});
|
|
5478
|
-
const axis = (0,
|
|
5828
|
+
const axis = (0, import_react31.useMemo)(() => {
|
|
5479
5829
|
if (!schema) {
|
|
5480
5830
|
return null;
|
|
5481
5831
|
}
|
|
5482
|
-
const timeFields = (0,
|
|
5832
|
+
const timeFields = (0, import_sdk11.fieldsFor)(schema.fields, "timeAxis");
|
|
5483
5833
|
const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
|
|
5484
|
-
return chosen && (0,
|
|
5834
|
+
return chosen && (0, import_sdk11.specFor)(chosen).capabilities.timeAxis ? chosen : null;
|
|
5485
5835
|
}, [schema, x]);
|
|
5486
|
-
const measure = (0,
|
|
5836
|
+
const measure = (0, import_react31.useMemo)(() => {
|
|
5487
5837
|
if (!schema || !y) {
|
|
5488
5838
|
return null;
|
|
5489
5839
|
}
|
|
5490
|
-
const candidates = (0,
|
|
5840
|
+
const candidates = (0, import_sdk11.fieldsAggregatableBy)(schema.fields, aggregate);
|
|
5491
5841
|
return candidates.find((field) => field.key === y) ?? null;
|
|
5492
5842
|
}, [schema, y, aggregate]);
|
|
5493
|
-
const buckets = (0,
|
|
5843
|
+
const buckets = (0, import_react31.useMemo)(
|
|
5494
5844
|
() => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
|
|
5495
5845
|
[records, axis, measure, aggregate, bucket, y]
|
|
5496
5846
|
);
|
|
5497
5847
|
if (error) {
|
|
5498
|
-
return /* @__PURE__ */ (0,
|
|
5848
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5499
5849
|
}
|
|
5500
5850
|
if (!schema || loading) {
|
|
5501
|
-
return /* @__PURE__ */ (0,
|
|
5851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5502
5852
|
}
|
|
5503
5853
|
if (!axis) {
|
|
5504
|
-
return /* @__PURE__ */ (0,
|
|
5854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
|
|
5505
5855
|
}
|
|
5506
5856
|
if (y && !measure) {
|
|
5507
|
-
return /* @__PURE__ */ (0,
|
|
5857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
|
|
5508
5858
|
}
|
|
5509
5859
|
const peak = Math.max(...buckets.map((entry) => entry.value), 0);
|
|
5510
5860
|
const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
|
|
5511
|
-
return /* @__PURE__ */ (0,
|
|
5512
|
-
/* @__PURE__ */ (0,
|
|
5513
|
-
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0,
|
|
5514
|
-
/* @__PURE__ */ (0,
|
|
5861
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
|
|
5862
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
|
|
5863
|
+
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-chart-col", children: [
|
|
5864
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5515
5865
|
"div",
|
|
5516
5866
|
{
|
|
5517
5867
|
className: "b316-chart-bar",
|
|
@@ -5519,18 +5869,18 @@ function Chart({
|
|
|
5519
5869
|
title: `${entry.label}: ${format(entry.value)}`
|
|
5520
5870
|
}
|
|
5521
5871
|
),
|
|
5522
|
-
/* @__PURE__ */ (0,
|
|
5872
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-chart-label", children: entry.label })
|
|
5523
5873
|
] }, entry.key)) }),
|
|
5524
|
-
/* @__PURE__ */ (0,
|
|
5525
|
-
/* @__PURE__ */ (0,
|
|
5526
|
-
/* @__PURE__ */ (0,
|
|
5527
|
-
/* @__PURE__ */ (0,
|
|
5528
|
-
/* @__PURE__ */ (0,
|
|
5529
|
-
/* @__PURE__ */ (0,
|
|
5874
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("details", { className: "b316-chart-data", children: [
|
|
5875
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("summary", { children: "Values" }),
|
|
5876
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("table", { className: "b316-table", children: [
|
|
5877
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
|
|
5878
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: axis.label }),
|
|
5879
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
|
|
5530
5880
|
] }) }),
|
|
5531
|
-
/* @__PURE__ */ (0,
|
|
5532
|
-
/* @__PURE__ */ (0,
|
|
5533
|
-
/* @__PURE__ */ (0,
|
|
5881
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
|
|
5882
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: entry.label }),
|
|
5883
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: format(entry.value) })
|
|
5534
5884
|
] }, entry.key)) })
|
|
5535
5885
|
] })
|
|
5536
5886
|
] })
|
|
@@ -5588,9 +5938,9 @@ function combine(values, aggregate) {
|
|
|
5588
5938
|
}
|
|
5589
5939
|
|
|
5590
5940
|
// src/RecordDetail.tsx
|
|
5591
|
-
var
|
|
5592
|
-
var
|
|
5593
|
-
var
|
|
5941
|
+
var import_sdk12 = require("@base316/sdk");
|
|
5942
|
+
var import_react32 = require("react");
|
|
5943
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
5594
5944
|
function RecordDetail({
|
|
5595
5945
|
collection,
|
|
5596
5946
|
recordId,
|
|
@@ -5606,23 +5956,23 @@ function RecordDetail({
|
|
|
5606
5956
|
tenant,
|
|
5607
5957
|
recordId
|
|
5608
5958
|
});
|
|
5609
|
-
const [editing, setEditing] = (0,
|
|
5959
|
+
const [editing, setEditing] = (0, import_react32.useState)(false);
|
|
5610
5960
|
const record = records.find((candidate) => candidate.id === recordId);
|
|
5611
5961
|
if (error) {
|
|
5612
|
-
return /* @__PURE__ */ (0,
|
|
5962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5613
5963
|
}
|
|
5614
5964
|
if (!schema || loading) {
|
|
5615
|
-
return /* @__PURE__ */ (0,
|
|
5965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5616
5966
|
}
|
|
5617
5967
|
if (!record) {
|
|
5618
|
-
return /* @__PURE__ */ (0,
|
|
5968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
5619
5969
|
"That ",
|
|
5620
5970
|
schema.name.toLowerCase(),
|
|
5621
5971
|
" is not available."
|
|
5622
5972
|
] });
|
|
5623
5973
|
}
|
|
5624
5974
|
if (editing) {
|
|
5625
|
-
return /* @__PURE__ */ (0,
|
|
5975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5626
5976
|
RecordForm,
|
|
5627
5977
|
{
|
|
5628
5978
|
collection,
|
|
@@ -5636,12 +5986,12 @@ function RecordDetail({
|
|
|
5636
5986
|
);
|
|
5637
5987
|
}
|
|
5638
5988
|
const writable = canWrite && !readOnly;
|
|
5639
|
-
return /* @__PURE__ */ (0,
|
|
5640
|
-
/* @__PURE__ */ (0,
|
|
5641
|
-
/* @__PURE__ */ (0,
|
|
5642
|
-
/* @__PURE__ */ (0,
|
|
5643
|
-
writable ? /* @__PURE__ */ (0,
|
|
5644
|
-
writable ? /* @__PURE__ */ (0,
|
|
5989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
|
|
5990
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-head", children: [
|
|
5991
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
|
|
5992
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-actions", children: [
|
|
5993
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
|
|
5994
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5645
5995
|
ConfirmButton,
|
|
5646
5996
|
{
|
|
5647
5997
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5654,15 +6004,15 @@ function RecordDetail({
|
|
|
5654
6004
|
children: "Delete"
|
|
5655
6005
|
}
|
|
5656
6006
|
) : null,
|
|
5657
|
-
onClose ? /* @__PURE__ */ (0,
|
|
6007
|
+
onClose ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
|
|
5658
6008
|
] })
|
|
5659
6009
|
] }),
|
|
5660
|
-
/* @__PURE__ */ (0,
|
|
5661
|
-
/* @__PURE__ */ (0,
|
|
6010
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-row", children: [
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("dt", { className: "b316-label", children: [
|
|
5662
6012
|
field.label,
|
|
5663
|
-
(0,
|
|
6013
|
+
(0, import_sdk12.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
|
|
5664
6014
|
] }),
|
|
5665
|
-
/* @__PURE__ */ (0,
|
|
6015
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5666
6016
|
FieldCell,
|
|
5667
6017
|
{
|
|
5668
6018
|
value: record.fields[field.key] ?? null,
|
|
@@ -5676,8 +6026,8 @@ function RecordDetail({
|
|
|
5676
6026
|
}
|
|
5677
6027
|
|
|
5678
6028
|
// src/SubscriptionManager.tsx
|
|
5679
|
-
var
|
|
5680
|
-
var
|
|
6029
|
+
var import_react33 = require("react");
|
|
6030
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
5681
6031
|
function statusLabel(status2) {
|
|
5682
6032
|
const words = status2.toLowerCase().split("_");
|
|
5683
6033
|
return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
|
|
@@ -5717,16 +6067,16 @@ function SubscriptionManager({
|
|
|
5717
6067
|
style
|
|
5718
6068
|
}) {
|
|
5719
6069
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
5720
|
-
const [subscription, setSubscription] = (0,
|
|
5721
|
-
const [loading, setLoading] = (0,
|
|
5722
|
-
const [managedBy, setManagedBy] = (0,
|
|
5723
|
-
const [schedule, setSchedule] = (0,
|
|
5724
|
-
const [busy, setBusy] = (0,
|
|
5725
|
-
const [error, setError] = (0,
|
|
5726
|
-
const [step, setStep] = (0,
|
|
5727
|
-
const [reason, setReason] = (0,
|
|
5728
|
-
const [comment, setComment] = (0,
|
|
5729
|
-
const load = (0,
|
|
6070
|
+
const [subscription, setSubscription] = (0, import_react33.useState)(null);
|
|
6071
|
+
const [loading, setLoading] = (0, import_react33.useState)(true);
|
|
6072
|
+
const [managedBy, setManagedBy] = (0, import_react33.useState)(null);
|
|
6073
|
+
const [schedule, setSchedule] = (0, import_react33.useState)([]);
|
|
6074
|
+
const [busy, setBusy] = (0, import_react33.useState)(false);
|
|
6075
|
+
const [error, setError] = (0, import_react33.useState)(null);
|
|
6076
|
+
const [step, setStep] = (0, import_react33.useState)({ kind: "idle" });
|
|
6077
|
+
const [reason, setReason] = (0, import_react33.useState)(null);
|
|
6078
|
+
const [comment, setComment] = (0, import_react33.useState)("");
|
|
6079
|
+
const load = (0, import_react33.useCallback)(async () => {
|
|
5730
6080
|
if (!token) {
|
|
5731
6081
|
setSubscription(null);
|
|
5732
6082
|
setLoading(false);
|
|
@@ -5744,7 +6094,7 @@ function SubscriptionManager({
|
|
|
5744
6094
|
setLoading(false);
|
|
5745
6095
|
}
|
|
5746
6096
|
}, [client, token]);
|
|
5747
|
-
(0,
|
|
6097
|
+
(0, import_react33.useEffect)(() => {
|
|
5748
6098
|
void load();
|
|
5749
6099
|
}, [load]);
|
|
5750
6100
|
const act = async (change, failure) => {
|
|
@@ -5762,29 +6112,29 @@ function SubscriptionManager({
|
|
|
5762
6112
|
}
|
|
5763
6113
|
};
|
|
5764
6114
|
if (sessionLoading || loading) {
|
|
5765
|
-
return /* @__PURE__ */ (0,
|
|
6115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5766
6116
|
}
|
|
5767
6117
|
if (!token) {
|
|
5768
|
-
return /* @__PURE__ */ (0,
|
|
6118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
|
|
5769
6119
|
}
|
|
5770
6120
|
if (error) {
|
|
5771
|
-
return /* @__PURE__ */ (0,
|
|
6121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5772
6122
|
}
|
|
5773
6123
|
if (!subscription) {
|
|
5774
|
-
return /* @__PURE__ */ (0,
|
|
6124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
|
|
5775
6125
|
}
|
|
5776
6126
|
const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
|
|
5777
6127
|
const next = schedule[0] ?? null;
|
|
5778
6128
|
const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
|
|
5779
|
-
return /* @__PURE__ */ (0,
|
|
5780
|
-
error ? /* @__PURE__ */ (0,
|
|
5781
|
-
/* @__PURE__ */ (0,
|
|
5782
|
-
/* @__PURE__ */ (0,
|
|
6129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
6130
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6131
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
|
|
5783
6133
|
statusLabel(subscription.status),
|
|
5784
6134
|
" \xB7 ",
|
|
5785
6135
|
subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
|
|
5786
6136
|
] }),
|
|
5787
|
-
next && !managedBy ? /* @__PURE__ */ (0,
|
|
6137
|
+
next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
|
|
5788
6138
|
"Moves to ",
|
|
5789
6139
|
next.plan.name,
|
|
5790
6140
|
" on ",
|
|
@@ -5792,7 +6142,7 @@ function SubscriptionManager({
|
|
|
5792
6142
|
". You keep ",
|
|
5793
6143
|
subscription.planVersion.plan.name,
|
|
5794
6144
|
" until then.",
|
|
5795
|
-
/* @__PURE__ */ (0,
|
|
6145
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5796
6146
|
"button",
|
|
5797
6147
|
{
|
|
5798
6148
|
type: "button",
|
|
@@ -5817,17 +6167,17 @@ function SubscriptionManager({
|
|
|
5817
6167
|
}
|
|
5818
6168
|
) })
|
|
5819
6169
|
] }) : null,
|
|
5820
|
-
managedBy ? /* @__PURE__ */ (0,
|
|
6170
|
+
managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5821
6171
|
"Provided by ",
|
|
5822
6172
|
managedBy.name ?? "the organization that manages your account",
|
|
5823
6173
|
". Ask them to change or cancel it."
|
|
5824
|
-
] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0,
|
|
5825
|
-
/* @__PURE__ */ (0,
|
|
6174
|
+
] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
|
|
6175
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5826
6176
|
"This subscription will not renew. You keep access until ",
|
|
5827
6177
|
renews,
|
|
5828
6178
|
"."
|
|
5829
6179
|
] }),
|
|
5830
|
-
/* @__PURE__ */ (0,
|
|
6180
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5831
6181
|
"button",
|
|
5832
6182
|
{
|
|
5833
6183
|
type: "button",
|
|
@@ -5837,14 +6187,14 @@ function SubscriptionManager({
|
|
|
5837
6187
|
children: busy ? "Working\u2026" : "Resume subscription"
|
|
5838
6188
|
}
|
|
5839
6189
|
)
|
|
5840
|
-
] }) : step.kind === "offer" ? /* @__PURE__ */ (0,
|
|
5841
|
-
/* @__PURE__ */ (0,
|
|
5842
|
-
/* @__PURE__ */ (0,
|
|
6190
|
+
] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
|
|
6191
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
|
|
6192
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
|
|
5843
6193
|
step.cancellation.offer,
|
|
5844
6194
|
step.cancellation.currency
|
|
5845
6195
|
)}.` }),
|
|
5846
|
-
/* @__PURE__ */ (0,
|
|
5847
|
-
/* @__PURE__ */ (0,
|
|
6196
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6197
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5848
6198
|
"button",
|
|
5849
6199
|
{
|
|
5850
6200
|
type: "button",
|
|
@@ -5857,7 +6207,7 @@ function SubscriptionManager({
|
|
|
5857
6207
|
children: busy ? "Working\u2026" : "Accept offer and stay"
|
|
5858
6208
|
}
|
|
5859
6209
|
),
|
|
5860
|
-
/* @__PURE__ */ (0,
|
|
6210
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5861
6211
|
"button",
|
|
5862
6212
|
{
|
|
5863
6213
|
type: "button",
|
|
@@ -5871,12 +6221,12 @@ function SubscriptionManager({
|
|
|
5871
6221
|
}
|
|
5872
6222
|
)
|
|
5873
6223
|
] }),
|
|
5874
|
-
/* @__PURE__ */ (0,
|
|
6224
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5875
6225
|
"If you cancel, you keep access until ",
|
|
5876
6226
|
renews,
|
|
5877
6227
|
"."
|
|
5878
6228
|
] })
|
|
5879
|
-
] }) : step.kind === "survey" ? /* @__PURE__ */ (0,
|
|
6229
|
+
] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
5880
6230
|
"form",
|
|
5881
6231
|
{
|
|
5882
6232
|
style: { marginTop: 14 },
|
|
@@ -5896,15 +6246,15 @@ function SubscriptionManager({
|
|
|
5896
6246
|
}, "Could not cancel. Try again.");
|
|
5897
6247
|
},
|
|
5898
6248
|
children: [
|
|
5899
|
-
/* @__PURE__ */ (0,
|
|
6249
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5900
6250
|
"You keep access until ",
|
|
5901
6251
|
renews,
|
|
5902
6252
|
". It will not renew after that."
|
|
5903
6253
|
] }),
|
|
5904
|
-
/* @__PURE__ */ (0,
|
|
5905
|
-
/* @__PURE__ */ (0,
|
|
5906
|
-
REASONS.map((option) => /* @__PURE__ */ (0,
|
|
5907
|
-
/* @__PURE__ */ (0,
|
|
6254
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("fieldset", { className: "b316-fieldset", children: [
|
|
6255
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
|
|
6256
|
+
REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
6257
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5908
6258
|
"input",
|
|
5909
6259
|
{
|
|
5910
6260
|
type: "radio",
|
|
@@ -5914,12 +6264,12 @@ function SubscriptionManager({
|
|
|
5914
6264
|
onChange: () => setReason(option.value)
|
|
5915
6265
|
}
|
|
5916
6266
|
),
|
|
5917
|
-
/* @__PURE__ */ (0,
|
|
6267
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: option.label })
|
|
5918
6268
|
] }, option.value))
|
|
5919
6269
|
] }),
|
|
5920
|
-
/* @__PURE__ */ (0,
|
|
5921
|
-
/* @__PURE__ */ (0,
|
|
5922
|
-
/* @__PURE__ */ (0,
|
|
6270
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { className: "b316-field", children: [
|
|
6271
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
|
|
6272
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5923
6273
|
"textarea",
|
|
5924
6274
|
{
|
|
5925
6275
|
className: "b316-input",
|
|
@@ -5930,9 +6280,9 @@ function SubscriptionManager({
|
|
|
5930
6280
|
}
|
|
5931
6281
|
)
|
|
5932
6282
|
] }),
|
|
5933
|
-
/* @__PURE__ */ (0,
|
|
5934
|
-
/* @__PURE__ */ (0,
|
|
5935
|
-
/* @__PURE__ */ (0,
|
|
6283
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6284
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
|
|
6285
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
5936
6286
|
"button",
|
|
5937
6287
|
{
|
|
5938
6288
|
type: "button",
|
|
@@ -5948,7 +6298,7 @@ function SubscriptionManager({
|
|
|
5948
6298
|
] })
|
|
5949
6299
|
]
|
|
5950
6300
|
}
|
|
5951
|
-
) : /* @__PURE__ */ (0,
|
|
6301
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5952
6302
|
"button",
|
|
5953
6303
|
{
|
|
5954
6304
|
type: "button",
|
|
@@ -5966,11 +6316,11 @@ function SubscriptionManager({
|
|
|
5966
6316
|
}
|
|
5967
6317
|
|
|
5968
6318
|
// src/BillingPortal.tsx
|
|
5969
|
-
var
|
|
6319
|
+
var import_react37 = require("react");
|
|
5970
6320
|
|
|
5971
6321
|
// src/CreditBalances.tsx
|
|
5972
|
-
var
|
|
5973
|
-
var
|
|
6322
|
+
var import_react34 = require("react");
|
|
6323
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
5974
6324
|
function units(value) {
|
|
5975
6325
|
return value === null ? "Unlimited" : Number(value).toLocaleString("en");
|
|
5976
6326
|
}
|
|
@@ -6005,10 +6355,10 @@ function Feature({
|
|
|
6005
6355
|
}) {
|
|
6006
6356
|
const { client, token } = useBase316();
|
|
6007
6357
|
const setting = feature.autoRecharge;
|
|
6008
|
-
const [busy, setBusy] = (0,
|
|
6009
|
-
const [error, setError] = (0,
|
|
6010
|
-
const [saved, setSaved] = (0,
|
|
6011
|
-
const [pack, setPack] = (0,
|
|
6358
|
+
const [busy, setBusy] = (0, import_react34.useState)(false);
|
|
6359
|
+
const [error, setError] = (0, import_react34.useState)(null);
|
|
6360
|
+
const [saved, setSaved] = (0, import_react34.useState)(null);
|
|
6361
|
+
const [pack, setPack] = (0, import_react34.useState)(feature.packs[0]?.id ?? "");
|
|
6012
6362
|
const unit = feature.unit ? ` ${feature.unit}` : "";
|
|
6013
6363
|
const warning = status(feature);
|
|
6014
6364
|
const buy = async () => {
|
|
@@ -6062,33 +6412,33 @@ function Feature({
|
|
|
6062
6412
|
setBusy(false);
|
|
6063
6413
|
}
|
|
6064
6414
|
};
|
|
6065
|
-
return /* @__PURE__ */ (0,
|
|
6066
|
-
/* @__PURE__ */ (0,
|
|
6067
|
-
/* @__PURE__ */ (0,
|
|
6068
|
-
/* @__PURE__ */ (0,
|
|
6415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
|
|
6416
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-label", children: feature.featureName }),
|
|
6417
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
|
|
6418
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: units(feature.remaining) }),
|
|
6069
6419
|
unit,
|
|
6070
6420
|
" left"
|
|
6071
6421
|
] }),
|
|
6072
|
-
/* @__PURE__ */ (0,
|
|
6422
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
|
|
6073
6423
|
feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
|
|
6074
6424
|
" ",
|
|
6075
6425
|
"\xB7 ",
|
|
6076
6426
|
units(feature.purchasedRemaining),
|
|
6077
6427
|
" purchased"
|
|
6078
6428
|
] }),
|
|
6079
|
-
warning && !managed ? /* @__PURE__ */ (0,
|
|
6080
|
-
error ? /* @__PURE__ */ (0,
|
|
6081
|
-
saved ? /* @__PURE__ */ (0,
|
|
6082
|
-
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0,
|
|
6083
|
-
/* @__PURE__ */ (0,
|
|
6084
|
-
/* @__PURE__ */ (0,
|
|
6429
|
+
warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
|
|
6430
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6431
|
+
saved ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
|
|
6432
|
+
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
6433
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
|
|
6434
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6085
6435
|
"select",
|
|
6086
6436
|
{
|
|
6087
6437
|
className: "b316-input",
|
|
6088
6438
|
"aria-label": "Pack to buy",
|
|
6089
6439
|
value: pack,
|
|
6090
6440
|
onChange: (event) => setPack(event.target.value),
|
|
6091
|
-
children: feature.packs.map((option) => /* @__PURE__ */ (0,
|
|
6441
|
+
children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("option", { value: option.id, children: [
|
|
6092
6442
|
option.name,
|
|
6093
6443
|
" \u2014 ",
|
|
6094
6444
|
units(option.units),
|
|
@@ -6097,7 +6447,7 @@ function Feature({
|
|
|
6097
6447
|
] }, option.id))
|
|
6098
6448
|
}
|
|
6099
6449
|
),
|
|
6100
|
-
/* @__PURE__ */ (0,
|
|
6450
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6101
6451
|
"button",
|
|
6102
6452
|
{
|
|
6103
6453
|
type: "button",
|
|
@@ -6108,19 +6458,19 @@ function Feature({
|
|
|
6108
6458
|
}
|
|
6109
6459
|
)
|
|
6110
6460
|
] }),
|
|
6111
|
-
/* @__PURE__ */ (0,
|
|
6112
|
-
/* @__PURE__ */ (0,
|
|
6113
|
-
/* @__PURE__ */ (0,
|
|
6461
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
|
|
6462
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-checkbox", children: [
|
|
6463
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
|
|
6114
6464
|
" ",
|
|
6115
6465
|
"Buy credits automatically when my balance runs low"
|
|
6116
6466
|
] }),
|
|
6117
|
-
/* @__PURE__ */ (0,
|
|
6118
|
-
/* @__PURE__ */ (0,
|
|
6467
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
|
|
6468
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
|
|
6119
6469
|
"When fewer than this many",
|
|
6120
6470
|
unit,
|
|
6121
6471
|
" are left"
|
|
6122
6472
|
] }),
|
|
6123
|
-
/* @__PURE__ */ (0,
|
|
6473
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6124
6474
|
"input",
|
|
6125
6475
|
{
|
|
6126
6476
|
className: "b316-input",
|
|
@@ -6131,21 +6481,21 @@ function Feature({
|
|
|
6131
6481
|
}
|
|
6132
6482
|
)
|
|
6133
6483
|
] }),
|
|
6134
|
-
/* @__PURE__ */ (0,
|
|
6135
|
-
/* @__PURE__ */ (0,
|
|
6136
|
-
/* @__PURE__ */ (0,
|
|
6484
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
|
|
6485
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "Buy" }),
|
|
6486
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6137
6487
|
"select",
|
|
6138
6488
|
{
|
|
6139
6489
|
className: "b316-input",
|
|
6140
6490
|
name: "creditPackId",
|
|
6141
6491
|
defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
|
|
6142
|
-
children: feature.packs.map((option) => /* @__PURE__ */ (0,
|
|
6492
|
+
children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("option", { value: option.id, children: option.name }, option.id))
|
|
6143
6493
|
}
|
|
6144
6494
|
)
|
|
6145
6495
|
] }),
|
|
6146
|
-
/* @__PURE__ */ (0,
|
|
6147
|
-
/* @__PURE__ */ (0,
|
|
6148
|
-
/* @__PURE__ */ (0,
|
|
6496
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
|
|
6497
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
|
|
6498
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6149
6499
|
"input",
|
|
6150
6500
|
{
|
|
6151
6501
|
className: "b316-input",
|
|
@@ -6155,13 +6505,13 @@ function Feature({
|
|
|
6155
6505
|
}
|
|
6156
6506
|
)
|
|
6157
6507
|
] }),
|
|
6158
|
-
/* @__PURE__ */ (0,
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6508
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
|
|
6509
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
|
|
6160
6510
|
"Spending at most (",
|
|
6161
6511
|
setting?.currency ?? feature.packs[0]?.currency ?? "USD",
|
|
6162
6512
|
") a month"
|
|
6163
6513
|
] }),
|
|
6164
|
-
/* @__PURE__ */ (0,
|
|
6514
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6165
6515
|
"input",
|
|
6166
6516
|
{
|
|
6167
6517
|
className: "b316-input",
|
|
@@ -6171,16 +6521,16 @@ function Feature({
|
|
|
6171
6521
|
}
|
|
6172
6522
|
)
|
|
6173
6523
|
] }),
|
|
6174
|
-
/* @__PURE__ */ (0,
|
|
6524
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
|
|
6175
6525
|
] })
|
|
6176
6526
|
] })
|
|
6177
6527
|
] });
|
|
6178
6528
|
}
|
|
6179
6529
|
function CreditBalances({ onChange, className, style }) {
|
|
6180
6530
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6181
|
-
const [state, setState] = (0,
|
|
6182
|
-
const [version, setVersion] = (0,
|
|
6183
|
-
(0,
|
|
6531
|
+
const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
|
|
6532
|
+
const [version, setVersion] = (0, import_react34.useState)(0);
|
|
6533
|
+
(0, import_react34.useEffect)(() => {
|
|
6184
6534
|
if (!token) return;
|
|
6185
6535
|
let cancelled = false;
|
|
6186
6536
|
client.billing.credits(token).then((credits2) => {
|
|
@@ -6193,24 +6543,24 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6193
6543
|
cancelled = true;
|
|
6194
6544
|
};
|
|
6195
6545
|
}, [client, token, version]);
|
|
6196
|
-
const wrap = (content) => /* @__PURE__ */ (0,
|
|
6546
|
+
const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
|
|
6197
6547
|
if (sessionLoading || !token || state.kind === "loading") return null;
|
|
6198
6548
|
if (state.kind === "error") {
|
|
6199
6549
|
return wrap(
|
|
6200
|
-
/* @__PURE__ */ (0,
|
|
6550
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
|
|
6201
6551
|
);
|
|
6202
6552
|
}
|
|
6203
6553
|
const { credits } = state;
|
|
6204
6554
|
if (credits.features.length === 0) return null;
|
|
6205
6555
|
return wrap(
|
|
6206
|
-
/* @__PURE__ */ (0,
|
|
6207
|
-
credits.managedBy ? /* @__PURE__ */ (0,
|
|
6556
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
|
|
6557
|
+
credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
|
|
6208
6558
|
"Credits for this account come from",
|
|
6209
6559
|
" ",
|
|
6210
6560
|
credits.managedBy.name ?? "the organization that manages it",
|
|
6211
6561
|
", which manages them."
|
|
6212
6562
|
] }) : null,
|
|
6213
|
-
credits.features.map((feature) => /* @__PURE__ */ (0,
|
|
6563
|
+
credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6214
6564
|
Feature,
|
|
6215
6565
|
{
|
|
6216
6566
|
feature,
|
|
@@ -6227,19 +6577,19 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6227
6577
|
}
|
|
6228
6578
|
|
|
6229
6579
|
// src/PaymentMethod.tsx
|
|
6230
|
-
var
|
|
6231
|
-
var
|
|
6580
|
+
var import_react35 = require("react");
|
|
6581
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6232
6582
|
function brandName(brand) {
|
|
6233
6583
|
if (!brand) return "Card";
|
|
6234
6584
|
return brand.charAt(0).toUpperCase() + brand.slice(1);
|
|
6235
6585
|
}
|
|
6236
6586
|
function PaymentMethod({ returnUrl, className, style }) {
|
|
6237
6587
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6238
|
-
const [state, setState] = (0,
|
|
6239
|
-
const [busy, setBusy] = (0,
|
|
6240
|
-
const [error, setError] = (0,
|
|
6241
|
-
const [version, setVersion] = (0,
|
|
6242
|
-
(0,
|
|
6588
|
+
const [state, setState] = (0, import_react35.useState)({ kind: "loading" });
|
|
6589
|
+
const [busy, setBusy] = (0, import_react35.useState)(false);
|
|
6590
|
+
const [error, setError] = (0, import_react35.useState)(null);
|
|
6591
|
+
const [version, setVersion] = (0, import_react35.useState)(0);
|
|
6592
|
+
(0, import_react35.useEffect)(() => {
|
|
6243
6593
|
if (!token) return;
|
|
6244
6594
|
let cancelled = false;
|
|
6245
6595
|
client.billing.paymentMethods(token).then((result) => {
|
|
@@ -6255,7 +6605,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6255
6605
|
cancelled = true;
|
|
6256
6606
|
};
|
|
6257
6607
|
}, [client, token, version]);
|
|
6258
|
-
const wrap = (content) => /* @__PURE__ */ (0,
|
|
6608
|
+
const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
|
|
6259
6609
|
if (sessionLoading) return wrap("Loading\u2026");
|
|
6260
6610
|
if (!token) return wrap("Sign in to manage your payment method.");
|
|
6261
6611
|
switch (state.kind) {
|
|
@@ -6263,11 +6613,11 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6263
6613
|
return wrap("Loading\u2026");
|
|
6264
6614
|
case "error":
|
|
6265
6615
|
return wrap(
|
|
6266
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
|
|
6267
6617
|
);
|
|
6268
6618
|
case "managed":
|
|
6269
6619
|
return wrap(
|
|
6270
|
-
/* @__PURE__ */ (0,
|
|
6620
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
|
|
6271
6621
|
);
|
|
6272
6622
|
}
|
|
6273
6623
|
const card = state.cards.find((saved) => saved.isDefault) ?? null;
|
|
@@ -6286,31 +6636,31 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6286
6636
|
}
|
|
6287
6637
|
};
|
|
6288
6638
|
return wrap(
|
|
6289
|
-
/* @__PURE__ */ (0,
|
|
6290
|
-
/* @__PURE__ */ (0,
|
|
6291
|
-
card ? /* @__PURE__ */ (0,
|
|
6292
|
-
/* @__PURE__ */ (0,
|
|
6639
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
6640
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Payment method" }),
|
|
6641
|
+
card ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
|
|
6642
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
|
|
6293
6643
|
brandName(card.brand),
|
|
6294
6644
|
" ending ",
|
|
6295
6645
|
card.last4 ?? "????"
|
|
6296
6646
|
] }),
|
|
6297
|
-
card.expMonth && card.expYear ? /* @__PURE__ */ (0,
|
|
6647
|
+
card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
|
|
6298
6648
|
"Expires ",
|
|
6299
6649
|
String(card.expMonth).padStart(2, "0"),
|
|
6300
6650
|
"/",
|
|
6301
6651
|
card.expYear
|
|
6302
6652
|
] }) : null
|
|
6303
|
-
] }) : /* @__PURE__ */ (0,
|
|
6304
|
-
others.length > 0 ? /* @__PURE__ */ (0,
|
|
6305
|
-
/* @__PURE__ */ (0,
|
|
6306
|
-
others.map((saved) => /* @__PURE__ */ (0,
|
|
6307
|
-
/* @__PURE__ */ (0,
|
|
6653
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "No card on file." }),
|
|
6654
|
+
others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { marginTop: 12 }, children: [
|
|
6655
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
|
|
6656
|
+
others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
|
|
6657
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
|
|
6308
6658
|
brandName(saved.brand),
|
|
6309
6659
|
" ending ",
|
|
6310
6660
|
saved.last4 ?? "????"
|
|
6311
6661
|
] }),
|
|
6312
|
-
/* @__PURE__ */ (0,
|
|
6313
|
-
/* @__PURE__ */ (0,
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
|
|
6663
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6314
6664
|
"button",
|
|
6315
6665
|
{
|
|
6316
6666
|
type: "button",
|
|
@@ -6324,7 +6674,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6324
6674
|
}
|
|
6325
6675
|
),
|
|
6326
6676
|
" ",
|
|
6327
|
-
/* @__PURE__ */ (0,
|
|
6677
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6328
6678
|
"button",
|
|
6329
6679
|
{
|
|
6330
6680
|
type: "button",
|
|
@@ -6340,8 +6690,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6340
6690
|
] })
|
|
6341
6691
|
] }, saved.id))
|
|
6342
6692
|
] }) : null,
|
|
6343
|
-
error ? /* @__PURE__ */ (0,
|
|
6344
|
-
/* @__PURE__ */ (0,
|
|
6693
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6694
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6345
6695
|
"button",
|
|
6346
6696
|
{
|
|
6347
6697
|
type: "button",
|
|
@@ -6370,8 +6720,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6370
6720
|
}
|
|
6371
6721
|
|
|
6372
6722
|
// src/PlanChangeReview.tsx
|
|
6373
|
-
var
|
|
6374
|
-
var
|
|
6723
|
+
var import_react36 = require("react");
|
|
6724
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
6375
6725
|
function money5(amount, currency) {
|
|
6376
6726
|
if (amount === null) return "\u2014";
|
|
6377
6727
|
const value = Number(amount);
|
|
@@ -6404,12 +6754,12 @@ function PlanChangeReview({
|
|
|
6404
6754
|
style
|
|
6405
6755
|
}) {
|
|
6406
6756
|
const { client, token } = useBase316();
|
|
6407
|
-
const [timing, setTiming] = (0,
|
|
6408
|
-
const [preview, setPreview] = (0,
|
|
6409
|
-
const [error, setError] = (0,
|
|
6410
|
-
const [needsCard, setNeedsCard] = (0,
|
|
6411
|
-
const [busy, setBusy] = (0,
|
|
6412
|
-
(0,
|
|
6757
|
+
const [timing, setTiming] = (0, import_react36.useState)(void 0);
|
|
6758
|
+
const [preview, setPreview] = (0, import_react36.useState)(null);
|
|
6759
|
+
const [error, setError] = (0, import_react36.useState)(null);
|
|
6760
|
+
const [needsCard, setNeedsCard] = (0, import_react36.useState)(false);
|
|
6761
|
+
const [busy, setBusy] = (0, import_react36.useState)(false);
|
|
6762
|
+
(0, import_react36.useEffect)(() => {
|
|
6413
6763
|
if (!token) return;
|
|
6414
6764
|
let cancelled = false;
|
|
6415
6765
|
client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
|
|
@@ -6426,7 +6776,7 @@ function PlanChangeReview({
|
|
|
6426
6776
|
cancelled = true;
|
|
6427
6777
|
};
|
|
6428
6778
|
}, [client, token, planVersionId, timing]);
|
|
6429
|
-
const confirm = (0,
|
|
6779
|
+
const confirm = (0, import_react36.useCallback)(async () => {
|
|
6430
6780
|
if (!token || !preview) return;
|
|
6431
6781
|
setBusy(true);
|
|
6432
6782
|
setError(null);
|
|
@@ -6447,7 +6797,7 @@ function PlanChangeReview({
|
|
|
6447
6797
|
setBusy(false);
|
|
6448
6798
|
}
|
|
6449
6799
|
}, [client, token, preview, planVersionId, onDone]);
|
|
6450
|
-
const addCard = (0,
|
|
6800
|
+
const addCard = (0, import_react36.useCallback)(async () => {
|
|
6451
6801
|
if (onNeedsCard) {
|
|
6452
6802
|
onNeedsCard();
|
|
6453
6803
|
return;
|
|
@@ -6461,12 +6811,12 @@ function PlanChangeReview({
|
|
|
6461
6811
|
setError("Cards cannot be added here right now.");
|
|
6462
6812
|
}
|
|
6463
6813
|
}, [client, token, onNeedsCard]);
|
|
6464
|
-
const card = (content) => /* @__PURE__ */ (0,
|
|
6814
|
+
const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
|
|
6465
6815
|
if (error && !preview) {
|
|
6466
6816
|
return card(
|
|
6467
|
-
/* @__PURE__ */ (0,
|
|
6468
|
-
/* @__PURE__ */ (0,
|
|
6469
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
6817
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
6818
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }),
|
|
6819
|
+
onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
|
|
6470
6820
|
] })
|
|
6471
6821
|
);
|
|
6472
6822
|
}
|
|
@@ -6479,26 +6829,26 @@ function PlanChangeReview({
|
|
|
6479
6829
|
const otherReason = preview.timings[other]?.reason ?? null;
|
|
6480
6830
|
const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
|
|
6481
6831
|
return card(
|
|
6482
|
-
/* @__PURE__ */ (0,
|
|
6483
|
-
/* @__PURE__ */ (0,
|
|
6832
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
6833
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-plan-name", children: [
|
|
6484
6834
|
"Change to ",
|
|
6485
6835
|
to.planName
|
|
6486
6836
|
] }),
|
|
6487
|
-
/* @__PURE__ */ (0,
|
|
6837
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
|
|
6488
6838
|
"From ",
|
|
6489
6839
|
from.planName
|
|
6490
6840
|
] }),
|
|
6491
|
-
error ? /* @__PURE__ */ (0,
|
|
6492
|
-
changes.length === 0 ? /* @__PURE__ */ (0,
|
|
6493
|
-
/* @__PURE__ */ (0,
|
|
6494
|
-
/* @__PURE__ */ (0,
|
|
6495
|
-
/* @__PURE__ */ (0,
|
|
6496
|
-
/* @__PURE__ */ (0,
|
|
6841
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6842
|
+
changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("table", { className: "b316-review-table", children: [
|
|
6843
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
|
|
6844
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: "Feature" }),
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: from.planName }),
|
|
6846
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: to.planName })
|
|
6497
6847
|
] }) }),
|
|
6498
|
-
/* @__PURE__ */ (0,
|
|
6499
|
-
/* @__PURE__ */ (0,
|
|
6500
|
-
/* @__PURE__ */ (0,
|
|
6501
|
-
/* @__PURE__ */ (0,
|
|
6848
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
|
|
6849
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: change.featureName }),
|
|
6850
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: limitText(change.before, change.type) }),
|
|
6851
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
6502
6852
|
"td",
|
|
6503
6853
|
{
|
|
6504
6854
|
className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
|
|
@@ -6507,40 +6857,40 @@ function PlanChangeReview({
|
|
|
6507
6857
|
)
|
|
6508
6858
|
] }, change.featureId)) })
|
|
6509
6859
|
] }),
|
|
6510
|
-
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0,
|
|
6860
|
+
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
|
|
6511
6861
|
"The change happens now. Your trial carries on until ",
|
|
6512
6862
|
day4(now.trialEndsAt),
|
|
6513
6863
|
", and nothing is charged before then."
|
|
6514
|
-
] }) : /* @__PURE__ */ (0,
|
|
6515
|
-
Number(now.credit) > 0 ? /* @__PURE__ */ (0,
|
|
6516
|
-
/* @__PURE__ */ (0,
|
|
6864
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
|
|
6865
|
+
Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
|
|
6866
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
|
|
6517
6867
|
"Credit for the unused part of ",
|
|
6518
6868
|
from.planName
|
|
6519
6869
|
] }),
|
|
6520
|
-
/* @__PURE__ */ (0,
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-num", children: [
|
|
6521
6871
|
"\u2212",
|
|
6522
6872
|
money5(now.credit, from.currency)
|
|
6523
6873
|
] })
|
|
6524
6874
|
] }) : null,
|
|
6525
|
-
Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0,
|
|
6526
|
-
/* @__PURE__ */ (0,
|
|
6527
|
-
/* @__PURE__ */ (0,
|
|
6875
|
+
Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
|
|
6876
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
|
|
6877
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
|
|
6528
6878
|
] }) : null,
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6879
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
|
|
6880
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
|
|
6531
6881
|
to.planName,
|
|
6532
6882
|
", ",
|
|
6533
6883
|
day4(now.newPeriod.start),
|
|
6534
6884
|
" \u2013 ",
|
|
6535
6885
|
day4(now.newPeriod.end)
|
|
6536
6886
|
] }),
|
|
6537
|
-
/* @__PURE__ */ (0,
|
|
6887
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
|
|
6538
6888
|
] }),
|
|
6539
|
-
now.net !== null ? /* @__PURE__ */ (0,
|
|
6540
|
-
/* @__PURE__ */ (0,
|
|
6541
|
-
/* @__PURE__ */ (0,
|
|
6889
|
+
now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
|
|
6890
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "Due now" }),
|
|
6891
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
|
|
6542
6892
|
] }) : null
|
|
6543
|
-
] }) : /* @__PURE__ */ (0,
|
|
6893
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
|
|
6544
6894
|
"You keep ",
|
|
6545
6895
|
from.planName,
|
|
6546
6896
|
" until ",
|
|
@@ -6553,7 +6903,7 @@ function PlanChangeReview({
|
|
|
6553
6903
|
preview.atPeriodEnd.nextInvoice.currency
|
|
6554
6904
|
)}.` : ""
|
|
6555
6905
|
] }),
|
|
6556
|
-
otherOpen ? /* @__PURE__ */ (0,
|
|
6906
|
+
otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
6557
6907
|
"button",
|
|
6558
6908
|
{
|
|
6559
6909
|
type: "button",
|
|
@@ -6564,12 +6914,12 @@ function PlanChangeReview({
|
|
|
6564
6914
|
},
|
|
6565
6915
|
children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
|
|
6566
6916
|
}
|
|
6567
|
-
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0,
|
|
6568
|
-
needsCard ? /* @__PURE__ */ (0,
|
|
6917
|
+
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
|
|
6918
|
+
needsCard ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", role: "status", children: [
|
|
6569
6919
|
"A card is needed for a change that is charged now.",
|
|
6570
|
-
/* @__PURE__ */ (0,
|
|
6571
|
-
] }) : /* @__PURE__ */ (0,
|
|
6572
|
-
/* @__PURE__ */ (0,
|
|
6920
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
|
|
6921
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-review-actions", children: [
|
|
6922
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
6573
6923
|
"button",
|
|
6574
6924
|
{
|
|
6575
6925
|
type: "button",
|
|
@@ -6579,7 +6929,7 @@ function PlanChangeReview({
|
|
|
6579
6929
|
children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
|
|
6580
6930
|
}
|
|
6581
6931
|
),
|
|
6582
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
6932
|
+
onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
|
|
6583
6933
|
"Keep ",
|
|
6584
6934
|
from.planName
|
|
6585
6935
|
] }) : null
|
|
@@ -6589,7 +6939,7 @@ function PlanChangeReview({
|
|
|
6589
6939
|
}
|
|
6590
6940
|
|
|
6591
6941
|
// src/BillingPortal.tsx
|
|
6592
|
-
var
|
|
6942
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
6593
6943
|
function BillingPortal({
|
|
6594
6944
|
returnUrl,
|
|
6595
6945
|
featuredPlanKey,
|
|
@@ -6599,12 +6949,12 @@ function BillingPortal({
|
|
|
6599
6949
|
style
|
|
6600
6950
|
}) {
|
|
6601
6951
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6602
|
-
const [overview, setOverview] = (0,
|
|
6603
|
-
const [failed, setFailed] = (0,
|
|
6604
|
-
const [version, setVersion] = (0,
|
|
6605
|
-
const [reviewing, setReviewing] = (0,
|
|
6606
|
-
const [notice, setNotice] = (0,
|
|
6607
|
-
(0,
|
|
6952
|
+
const [overview, setOverview] = (0, import_react37.useState)(null);
|
|
6953
|
+
const [failed, setFailed] = (0, import_react37.useState)(false);
|
|
6954
|
+
const [version, setVersion] = (0, import_react37.useState)(0);
|
|
6955
|
+
const [reviewing, setReviewing] = (0, import_react37.useState)(null);
|
|
6956
|
+
const [notice, setNotice] = (0, import_react37.useState)(null);
|
|
6957
|
+
(0, import_react37.useEffect)(() => {
|
|
6608
6958
|
if (!token) return;
|
|
6609
6959
|
let cancelled = false;
|
|
6610
6960
|
client.billing.subscription(token).then((result) => {
|
|
@@ -6623,28 +6973,28 @@ function BillingPortal({
|
|
|
6623
6973
|
cancelled = true;
|
|
6624
6974
|
};
|
|
6625
6975
|
}, [client, token, version]);
|
|
6626
|
-
const refresh = (0,
|
|
6976
|
+
const refresh = (0, import_react37.useCallback)(() => {
|
|
6627
6977
|
setNotice(null);
|
|
6628
6978
|
setVersion((value) => value + 1);
|
|
6629
6979
|
}, []);
|
|
6630
|
-
const shell = (content) => /* @__PURE__ */ (0,
|
|
6631
|
-
if (sessionLoading) return shell(/* @__PURE__ */ (0,
|
|
6632
|
-
if (!token) return shell(/* @__PURE__ */ (0,
|
|
6980
|
+
const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
|
|
6981
|
+
if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6982
|
+
if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
|
|
6633
6983
|
if (failed) {
|
|
6634
6984
|
return shell(
|
|
6635
|
-
/* @__PURE__ */ (0,
|
|
6985
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
|
|
6636
6986
|
);
|
|
6637
6987
|
}
|
|
6638
|
-
if (!overview) return shell(/* @__PURE__ */ (0,
|
|
6988
|
+
if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6639
6989
|
const { subscription, managedBy, quantityPriced } = overview;
|
|
6640
6990
|
const canChange = Boolean(subscription) && !managedBy;
|
|
6641
6991
|
return shell(
|
|
6642
|
-
/* @__PURE__ */ (0,
|
|
6643
|
-
notice ? /* @__PURE__ */ (0,
|
|
6644
|
-
/* @__PURE__ */ (0,
|
|
6645
|
-
canChange ? /* @__PURE__ */ (0,
|
|
6646
|
-
canChange && quantityPriced ? /* @__PURE__ */ (0,
|
|
6647
|
-
reviewing ? /* @__PURE__ */ (0,
|
|
6992
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
6993
|
+
notice ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
|
|
6994
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
|
|
6995
|
+
canChange ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
|
|
6996
|
+
canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
|
|
6997
|
+
reviewing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6648
6998
|
PlanChangeReview,
|
|
6649
6999
|
{
|
|
6650
7000
|
planVersionId: reviewing,
|
|
@@ -6657,9 +7007,9 @@ function BillingPortal({
|
|
|
6657
7007
|
);
|
|
6658
7008
|
}
|
|
6659
7009
|
}
|
|
6660
|
-
) : /* @__PURE__ */ (0,
|
|
6661
|
-
/* @__PURE__ */ (0,
|
|
6662
|
-
/* @__PURE__ */ (0,
|
|
7010
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("section", { children: [
|
|
7011
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
|
|
7012
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
6663
7013
|
PricingTable,
|
|
6664
7014
|
{
|
|
6665
7015
|
featuredPlanKey,
|
|
@@ -6671,17 +7021,17 @@ function BillingPortal({
|
|
|
6671
7021
|
`plans-${version}`
|
|
6672
7022
|
)
|
|
6673
7023
|
] }),
|
|
6674
|
-
/* @__PURE__ */ (0,
|
|
6675
|
-
managedBy ? null : /* @__PURE__ */ (0,
|
|
6676
|
-
/* @__PURE__ */ (0,
|
|
6677
|
-
billingDetails === void 0 ? /* @__PURE__ */ (0,
|
|
7024
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CreditBalances, {}, `credits-${version}`),
|
|
7025
|
+
managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
|
|
7026
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Invoices, {}, `invoices-${version}`),
|
|
7027
|
+
billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
|
|
6678
7028
|
] })
|
|
6679
7029
|
);
|
|
6680
7030
|
}
|
|
6681
7031
|
|
|
6682
7032
|
// src/ApiKeyManager.tsx
|
|
6683
|
-
var
|
|
6684
|
-
var
|
|
7033
|
+
var import_react38 = require("react");
|
|
7034
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
6685
7035
|
function duration(seconds) {
|
|
6686
7036
|
if (seconds % 3600 === 0) {
|
|
6687
7037
|
return `${seconds / 3600}h`;
|
|
@@ -6698,17 +7048,17 @@ function ApiKeyManager({
|
|
|
6698
7048
|
audience
|
|
6699
7049
|
}) {
|
|
6700
7050
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6701
|
-
const [resources, setResources] = (0,
|
|
6702
|
-
const [credentials, setCredentials] = (0,
|
|
6703
|
-
const [loading, setLoading] = (0,
|
|
6704
|
-
const [busy, setBusy] = (0,
|
|
6705
|
-
const [error, setError] = (0,
|
|
6706
|
-
const [creating, setCreating] = (0,
|
|
6707
|
-
const [name, setName] = (0,
|
|
6708
|
-
const [chosen, setChosen] = (0,
|
|
6709
|
-
const [resourceId, setResourceId] = (0,
|
|
6710
|
-
const [issued, setIssued] = (0,
|
|
6711
|
-
const load = (0,
|
|
7051
|
+
const [resources, setResources] = (0, import_react38.useState)([]);
|
|
7052
|
+
const [credentials, setCredentials] = (0, import_react38.useState)([]);
|
|
7053
|
+
const [loading, setLoading] = (0, import_react38.useState)(true);
|
|
7054
|
+
const [busy, setBusy] = (0, import_react38.useState)(false);
|
|
7055
|
+
const [error, setError] = (0, import_react38.useState)(null);
|
|
7056
|
+
const [creating, setCreating] = (0, import_react38.useState)(false);
|
|
7057
|
+
const [name, setName] = (0, import_react38.useState)("");
|
|
7058
|
+
const [chosen, setChosen] = (0, import_react38.useState)([]);
|
|
7059
|
+
const [resourceId, setResourceId] = (0, import_react38.useState)(null);
|
|
7060
|
+
const [issued, setIssued] = (0, import_react38.useState)(null);
|
|
7061
|
+
const load = (0, import_react38.useCallback)(async () => {
|
|
6712
7062
|
if (!token) {
|
|
6713
7063
|
setLoading(false);
|
|
6714
7064
|
return;
|
|
@@ -6729,20 +7079,20 @@ function ApiKeyManager({
|
|
|
6729
7079
|
setLoading(false);
|
|
6730
7080
|
}
|
|
6731
7081
|
}, [client, token, audience]);
|
|
6732
|
-
(0,
|
|
7082
|
+
(0, import_react38.useEffect)(() => {
|
|
6733
7083
|
void load();
|
|
6734
7084
|
}, [load]);
|
|
6735
7085
|
if (sessionLoading || loading) {
|
|
6736
|
-
return /* @__PURE__ */ (0,
|
|
7086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
6737
7087
|
}
|
|
6738
7088
|
if (!token) {
|
|
6739
|
-
return /* @__PURE__ */ (0,
|
|
7089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
|
|
6740
7090
|
}
|
|
6741
7091
|
if (error) {
|
|
6742
|
-
return /* @__PURE__ */ (0,
|
|
7092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
|
|
6743
7093
|
}
|
|
6744
7094
|
if (resources.length === 0) {
|
|
6745
|
-
return /* @__PURE__ */ (0,
|
|
7095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
|
|
6746
7096
|
}
|
|
6747
7097
|
const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
|
|
6748
7098
|
const reset = () => {
|
|
@@ -6751,37 +7101,37 @@ function ApiKeyManager({
|
|
|
6751
7101
|
setChosen([]);
|
|
6752
7102
|
setIssued(null);
|
|
6753
7103
|
};
|
|
6754
|
-
return /* @__PURE__ */ (0,
|
|
6755
|
-
error ? /* @__PURE__ */ (0,
|
|
6756
|
-
resources.length > 1 ? /* @__PURE__ */ (0,
|
|
7104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
7105
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
7106
|
+
resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6757
7107
|
"select",
|
|
6758
7108
|
{
|
|
6759
7109
|
className: "b316-input",
|
|
6760
7110
|
value: resource.id,
|
|
6761
7111
|
onChange: (event) => setResourceId(event.target.value),
|
|
6762
7112
|
style: { marginBottom: 14 },
|
|
6763
|
-
children: resources.map((item) => /* @__PURE__ */ (0,
|
|
7113
|
+
children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: item.id, children: item.name }, item.id))
|
|
6764
7114
|
}
|
|
6765
|
-
) : /* @__PURE__ */ (0,
|
|
6766
|
-
resource.rateLimit ? /* @__PURE__ */ (0,
|
|
7115
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: resource.name }),
|
|
7116
|
+
resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
|
|
6767
7117
|
resource.rateLimit.requestsPerWindow,
|
|
6768
7118
|
" requests per",
|
|
6769
7119
|
" ",
|
|
6770
7120
|
duration(resource.rateLimit.windowSeconds),
|
|
6771
7121
|
resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
|
|
6772
|
-
] }) : /* @__PURE__ */ (0,
|
|
6773
|
-
credentials.length === 0 ? /* @__PURE__ */ (0,
|
|
6774
|
-
/* @__PURE__ */ (0,
|
|
6775
|
-
/* @__PURE__ */ (0,
|
|
6776
|
-
/* @__PURE__ */ (0,
|
|
6777
|
-
/* @__PURE__ */ (0,
|
|
7122
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
|
|
7123
|
+
credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { className: "b316-list-item", children: [
|
|
7124
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
|
|
7125
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: credential.name }),
|
|
7126
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
|
|
7127
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: credential.clientId }),
|
|
6778
7128
|
credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
|
|
6779
7129
|
credential.disabled ? " \xB7 Disabled" : null
|
|
6780
7130
|
] }),
|
|
6781
|
-
/* @__PURE__ */ (0,
|
|
7131
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
|
|
6782
7132
|
] }),
|
|
6783
|
-
/* @__PURE__ */ (0,
|
|
6784
|
-
/* @__PURE__ */ (0,
|
|
7133
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6785
7135
|
"button",
|
|
6786
7136
|
{
|
|
6787
7137
|
type: "button",
|
|
@@ -6810,7 +7160,7 @@ function ApiKeyManager({
|
|
|
6810
7160
|
children: "Rotate"
|
|
6811
7161
|
}
|
|
6812
7162
|
),
|
|
6813
|
-
/* @__PURE__ */ (0,
|
|
7163
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6814
7164
|
ConfirmButton,
|
|
6815
7165
|
{
|
|
6816
7166
|
className: "b316-button b316-button-secondary",
|
|
@@ -6834,11 +7184,11 @@ function ApiKeyManager({
|
|
|
6834
7184
|
)
|
|
6835
7185
|
] })
|
|
6836
7186
|
] }, credential.clientId)) }),
|
|
6837
|
-
issued ? /* @__PURE__ */ (0,
|
|
6838
|
-
/* @__PURE__ */ (0,
|
|
7187
|
+
issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
|
|
7188
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", { children: "Copy this now." }),
|
|
6839
7189
|
" It is shown once and cannot be retrieved again.",
|
|
6840
|
-
/* @__PURE__ */ (0,
|
|
6841
|
-
/* @__PURE__ */ (0,
|
|
7190
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
|
|
7191
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6842
7192
|
"button",
|
|
6843
7193
|
{
|
|
6844
7194
|
type: "button",
|
|
@@ -6851,7 +7201,7 @@ function ApiKeyManager({
|
|
|
6851
7201
|
children: "Copy"
|
|
6852
7202
|
}
|
|
6853
7203
|
),
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
7204
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6855
7205
|
"button",
|
|
6856
7206
|
{
|
|
6857
7207
|
type: "button",
|
|
@@ -6862,8 +7212,8 @@ function ApiKeyManager({
|
|
|
6862
7212
|
}
|
|
6863
7213
|
)
|
|
6864
7214
|
] }) : null,
|
|
6865
|
-
creating && !issued ? /* @__PURE__ */ (0,
|
|
6866
|
-
/* @__PURE__ */ (0,
|
|
7215
|
+
creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 14 }, children: [
|
|
7216
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6867
7217
|
"input",
|
|
6868
7218
|
{
|
|
6869
7219
|
className: "b316-input",
|
|
@@ -6872,9 +7222,9 @@ function ApiKeyManager({
|
|
|
6872
7222
|
onChange: (event) => setName(event.target.value)
|
|
6873
7223
|
}
|
|
6874
7224
|
),
|
|
6875
|
-
/* @__PURE__ */ (0,
|
|
6876
|
-
resource.availableScopes.map((scope) => /* @__PURE__ */ (0,
|
|
6877
|
-
/* @__PURE__ */ (0,
|
|
7225
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 10 }, children: [
|
|
7226
|
+
resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox", children: [
|
|
7227
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6878
7228
|
"input",
|
|
6879
7229
|
{
|
|
6880
7230
|
type: "checkbox",
|
|
@@ -6884,19 +7234,19 @@ function ApiKeyManager({
|
|
|
6884
7234
|
)
|
|
6885
7235
|
}
|
|
6886
7236
|
),
|
|
6887
|
-
/* @__PURE__ */ (0,
|
|
6888
|
-
scope.description ? /* @__PURE__ */ (0,
|
|
7237
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
|
|
7238
|
+
scope.description ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "b316-muted", children: [
|
|
6889
7239
|
" \u2014 ",
|
|
6890
7240
|
scope.description
|
|
6891
7241
|
] }) : null
|
|
6892
7242
|
] }, scope.key)),
|
|
6893
|
-
resource.lockedScopes.map((scope) => /* @__PURE__ */ (0,
|
|
6894
|
-
/* @__PURE__ */ (0,
|
|
6895
|
-
/* @__PURE__ */ (0,
|
|
6896
|
-
/* @__PURE__ */ (0,
|
|
7243
|
+
resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
|
|
7244
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "checkbox", disabled: true }),
|
|
7245
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
|
|
7246
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: " \u2014 not included in your plan" })
|
|
6897
7247
|
] }, scope.key))
|
|
6898
7248
|
] }),
|
|
6899
|
-
/* @__PURE__ */ (0,
|
|
7249
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6900
7250
|
"button",
|
|
6901
7251
|
{
|
|
6902
7252
|
type: "button",
|
|
@@ -6930,7 +7280,7 @@ function ApiKeyManager({
|
|
|
6930
7280
|
children: "Create key"
|
|
6931
7281
|
}
|
|
6932
7282
|
),
|
|
6933
|
-
/* @__PURE__ */ (0,
|
|
7283
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6934
7284
|
"button",
|
|
6935
7285
|
{
|
|
6936
7286
|
type: "button",
|
|
@@ -6941,7 +7291,7 @@ function ApiKeyManager({
|
|
|
6941
7291
|
}
|
|
6942
7292
|
)
|
|
6943
7293
|
] }) : null,
|
|
6944
|
-
!creating && !issued ? /* @__PURE__ */ (0,
|
|
7294
|
+
!creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6945
7295
|
"button",
|
|
6946
7296
|
{
|
|
6947
7297
|
type: "button",
|
|
@@ -7016,26 +7366,45 @@ var MANIFEST = [
|
|
|
7016
7366
|
{
|
|
7017
7367
|
name: "SignIn",
|
|
7018
7368
|
kind: "component",
|
|
7019
|
-
summary: "
|
|
7369
|
+
summary: "Sign in the ways the environment offers \u2014 password, magic link, passkeys, text message, social providers and SSO, as switched on in the dashboard (`GET /v1/auth/methods`).",
|
|
7020
7370
|
useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
|
|
7021
7371
|
requires: [],
|
|
7022
7372
|
props: [
|
|
7023
7373
|
{ name: "onSignedIn", summary: "Called once a session exists.", required: false },
|
|
7374
|
+
{
|
|
7375
|
+
name: "password",
|
|
7376
|
+
summary: "`false` hides the password form. Every method prop can only turn a method off.",
|
|
7377
|
+
required: false
|
|
7378
|
+
},
|
|
7024
7379
|
{
|
|
7025
7380
|
name: "passkeys",
|
|
7026
|
-
summary: "
|
|
7381
|
+
summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
|
|
7027
7382
|
required: false
|
|
7028
7383
|
},
|
|
7384
|
+
{ name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
|
|
7029
7385
|
{
|
|
7030
7386
|
name: "magicLinkRedirectUrl",
|
|
7031
|
-
summary: "Where an emailed link lands
|
|
7387
|
+
summary: "Where an emailed link lands; defaults to the page rendering the form, which redeems `?token=`. Must be on the environment's redirect allow-list.",
|
|
7388
|
+
required: false
|
|
7389
|
+
},
|
|
7390
|
+
{ name: "phone", summary: "`false` hides text-message codes.", required: false },
|
|
7391
|
+
{
|
|
7392
|
+
name: "social",
|
|
7393
|
+
summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
|
|
7394
|
+
required: false
|
|
7395
|
+
},
|
|
7396
|
+
{ name: "sso", summary: '`false` hides "Sign in with SSO".', required: false },
|
|
7397
|
+
{
|
|
7398
|
+
name: "socialRedirectUrl",
|
|
7399
|
+
summary: "Your server route a social or SSO sign-in returns to with `?code=&state=`: check `state` against the `b316_oauth_state` cookie (`readOAuthState`), then `base316.auth.exchangeCode` with the secret key. On the redirect allow-list. Without it no social or SSO button is shown.",
|
|
7032
7400
|
required: false
|
|
7033
7401
|
},
|
|
7034
7402
|
{
|
|
7035
|
-
name: "
|
|
7036
|
-
summary: "
|
|
7403
|
+
name: "socialState",
|
|
7404
|
+
summary: "A short value carried through a social or SSO sign-in, returned by `readOAuthState`.",
|
|
7037
7405
|
required: false
|
|
7038
7406
|
},
|
|
7407
|
+
{ name: "labels", summary: "Wording for the form, for translation.", required: false },
|
|
7039
7408
|
{
|
|
7040
7409
|
name: "secondFactorLabels",
|
|
7041
7410
|
summary: "Wording for the second-factor step (code box, or enrolment when the environment requires a factor and the user has none), for translation. English when omitted.",
|
|
@@ -7045,6 +7414,38 @@ var MANIFEST = [
|
|
|
7045
7414
|
],
|
|
7046
7415
|
seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
|
|
7047
7416
|
},
|
|
7417
|
+
{
|
|
7418
|
+
name: "SocialSignIn",
|
|
7419
|
+
kind: "component",
|
|
7420
|
+
summary: `The environment's social sign-in buttons alone ("Continue with Google"), for a sign-in or sign-up form you draw yourself.`,
|
|
7421
|
+
useWhen: "Your own form needs the social providers switched on in the dashboard. SignIn and SignUp already include them.",
|
|
7422
|
+
requires: [],
|
|
7423
|
+
props: [
|
|
7424
|
+
{
|
|
7425
|
+
name: "socialRedirectUrl",
|
|
7426
|
+
summary: "Your server route the code lands on with `?code=&state=`; check with `readOAuthState`, redeem with `exchangeCode`. On the redirect allow-list. Without it nothing is drawn.",
|
|
7427
|
+
required: false
|
|
7428
|
+
},
|
|
7429
|
+
{
|
|
7430
|
+
name: "socialState",
|
|
7431
|
+
summary: "A short value carried through, returned by `readOAuthState`.",
|
|
7432
|
+
required: false
|
|
7433
|
+
},
|
|
7434
|
+
{
|
|
7435
|
+
name: "social",
|
|
7436
|
+
summary: "`false` hides every button; a list of slugs keeps only those providers.",
|
|
7437
|
+
required: false
|
|
7438
|
+
},
|
|
7439
|
+
{
|
|
7440
|
+
name: "intent",
|
|
7441
|
+
summary: "`sign-up` hides the buttons when the environment is closed to new accounts.",
|
|
7442
|
+
required: false
|
|
7443
|
+
},
|
|
7444
|
+
{ name: "divider", summary: 'Draw an "or" rule under the buttons.', required: false },
|
|
7445
|
+
{ name: "labels", summary: "`continueWith` and `or`, for translation.", required: false }
|
|
7446
|
+
],
|
|
7447
|
+
seeAlso: ["SignIn", "SignUp"]
|
|
7448
|
+
},
|
|
7048
7449
|
{
|
|
7049
7450
|
name: "SignUp",
|
|
7050
7451
|
kind: "component",
|
|
@@ -7073,6 +7474,21 @@ var MANIFEST = [
|
|
|
7073
7474
|
summary: "Wording for the second-factor step, for translation.",
|
|
7074
7475
|
required: false
|
|
7075
7476
|
},
|
|
7477
|
+
{
|
|
7478
|
+
name: "social",
|
|
7479
|
+
summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
|
|
7480
|
+
required: false
|
|
7481
|
+
},
|
|
7482
|
+
{
|
|
7483
|
+
name: "socialRedirectUrl",
|
|
7484
|
+
summary: "Where a social sign-up returns with `?code=&state=`, as on SignIn. Without it no social button is shown.",
|
|
7485
|
+
required: false
|
|
7486
|
+
},
|
|
7487
|
+
{
|
|
7488
|
+
name: "socialState",
|
|
7489
|
+
summary: "A short value carried through a social sign-up, returned by `readOAuthState`.",
|
|
7490
|
+
required: false
|
|
7491
|
+
},
|
|
7076
7492
|
...appearance
|
|
7077
7493
|
],
|
|
7078
7494
|
seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
|
|
@@ -7845,6 +8261,7 @@ function componentsRequiring(requirement) {
|
|
|
7845
8261
|
SecondFactorStep,
|
|
7846
8262
|
SignIn,
|
|
7847
8263
|
SignUp,
|
|
8264
|
+
SocialSignIn,
|
|
7848
8265
|
SubscriptionManager,
|
|
7849
8266
|
TeamMembers,
|
|
7850
8267
|
TwoFactorManager,
|