@base316/react 0.6.0 → 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 +36 -0
- package/dist/index.cjs +1389 -973
- 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 +1330 -912
- 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/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/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; }
|
|
@@ -1673,8 +1691,8 @@ function BillingDetailsForm({
|
|
|
1673
1691
|
}
|
|
1674
1692
|
|
|
1675
1693
|
// src/SignIn.tsx
|
|
1676
|
-
var
|
|
1677
|
-
var
|
|
1694
|
+
var import_sdk4 = require("@base316/sdk");
|
|
1695
|
+
var import_react8 = require("react");
|
|
1678
1696
|
|
|
1679
1697
|
// src/SecondFactorStep.tsx
|
|
1680
1698
|
var import_sdk2 = require("@base316/sdk");
|
|
@@ -2063,33 +2081,230 @@ function SecondFactorStep({
|
|
|
2063
2081
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cls("b316-mfa", className), style, children: body });
|
|
2064
2082
|
}
|
|
2065
2083
|
|
|
2066
|
-
// 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
|
|
2067
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
|
+
};
|
|
2068
2249
|
function SignIn({
|
|
2069
2250
|
onSignedIn,
|
|
2070
|
-
|
|
2251
|
+
password: passwordProp,
|
|
2252
|
+
passkeys: passkeysProp,
|
|
2253
|
+
magicLink: magicLinkProp,
|
|
2071
2254
|
magicLinkRedirectUrl,
|
|
2072
|
-
phone
|
|
2255
|
+
phone: phoneProp,
|
|
2256
|
+
social: socialProp,
|
|
2257
|
+
sso: ssoProp,
|
|
2258
|
+
socialRedirectUrl,
|
|
2259
|
+
socialState,
|
|
2260
|
+
labels: overrides,
|
|
2073
2261
|
secondFactorLabels,
|
|
2074
2262
|
className,
|
|
2075
2263
|
style
|
|
2076
2264
|
}) {
|
|
2265
|
+
const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
|
|
2077
2266
|
const { client, setToken } = useBase316();
|
|
2078
|
-
const
|
|
2079
|
-
const [
|
|
2080
|
-
const [
|
|
2081
|
-
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);
|
|
2082
2273
|
const pendingChallenge = pending?.challengeToken ?? null;
|
|
2083
|
-
const [phoneNumber, setPhoneNumber] = (0,
|
|
2084
|
-
const [phoneChallenge, setPhoneChallenge] = (0,
|
|
2274
|
+
const [phoneNumber, setPhoneNumber] = (0, import_react8.useState)("");
|
|
2275
|
+
const [phoneChallenge, setPhoneChallenge] = (0, import_react8.useState)(
|
|
2085
2276
|
null
|
|
2086
2277
|
);
|
|
2087
|
-
const [error, setError] = (0,
|
|
2088
|
-
const [busy, setBusy] = (0,
|
|
2089
|
-
const [passkeyReady, setPasskeyReady] = (0,
|
|
2090
|
-
const [
|
|
2091
|
-
const [linkSent, setLinkSent] = (0,
|
|
2092
|
-
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;
|
|
2093
2308
|
const signInWithPasskey = async (conditional, signal) => {
|
|
2094
2309
|
if (!conditional) {
|
|
2095
2310
|
setBusy(true);
|
|
@@ -2103,11 +2318,11 @@ function SignIn({
|
|
|
2103
2318
|
if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
|
|
2104
2319
|
return;
|
|
2105
2320
|
}
|
|
2106
|
-
if (cause instanceof
|
|
2321
|
+
if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
|
|
2107
2322
|
setError(cause.message);
|
|
2108
2323
|
} else if (!conditional) {
|
|
2109
2324
|
console.error("[base316] passkey sign-in failed", cause);
|
|
2110
|
-
setError(
|
|
2325
|
+
setError(labels.passkeyFailed);
|
|
2111
2326
|
}
|
|
2112
2327
|
} finally {
|
|
2113
2328
|
if (!conditional) {
|
|
@@ -2115,14 +2330,15 @@ function SignIn({
|
|
|
2115
2330
|
}
|
|
2116
2331
|
}
|
|
2117
2332
|
};
|
|
2118
|
-
(0,
|
|
2119
|
-
if (!
|
|
2333
|
+
(0, import_react8.useEffect)(() => {
|
|
2334
|
+
if (!passkeysWanted || !(0, import_sdk4.isPasskeySupported)() || pendingChallenge) {
|
|
2335
|
+
setPasskeyReady(false);
|
|
2120
2336
|
return;
|
|
2121
2337
|
}
|
|
2122
2338
|
setPasskeyReady(true);
|
|
2123
2339
|
const controller = new AbortController();
|
|
2124
2340
|
abortRef.current = controller;
|
|
2125
|
-
void (0,
|
|
2341
|
+
void (0, import_sdk4.isPasskeyAutofillAvailable)().then((available) => {
|
|
2126
2342
|
if (available && !controller.signal.aborted) {
|
|
2127
2343
|
void signInWithPasskey(true, controller.signal);
|
|
2128
2344
|
}
|
|
@@ -2130,8 +2346,8 @@ function SignIn({
|
|
|
2130
2346
|
return () => {
|
|
2131
2347
|
controller.abort();
|
|
2132
2348
|
};
|
|
2133
|
-
}, [
|
|
2134
|
-
(0,
|
|
2349
|
+
}, [passkeysWanted, pendingChallenge]);
|
|
2350
|
+
(0, import_react8.useEffect)(() => {
|
|
2135
2351
|
if (typeof window === "undefined") {
|
|
2136
2352
|
return;
|
|
2137
2353
|
}
|
|
@@ -2147,7 +2363,7 @@ function SignIn({
|
|
|
2147
2363
|
if (cancelled) {
|
|
2148
2364
|
return;
|
|
2149
2365
|
}
|
|
2150
|
-
if ((0,
|
|
2366
|
+
if ((0, import_sdk4.needsSecondFactor)(result)) {
|
|
2151
2367
|
setPending(result);
|
|
2152
2368
|
return;
|
|
2153
2369
|
}
|
|
@@ -2155,7 +2371,7 @@ function SignIn({
|
|
|
2155
2371
|
onSignedIn?.();
|
|
2156
2372
|
}).catch(() => {
|
|
2157
2373
|
if (!cancelled) {
|
|
2158
|
-
setError(
|
|
2374
|
+
setError(labels.linkInvalid);
|
|
2159
2375
|
}
|
|
2160
2376
|
});
|
|
2161
2377
|
return () => {
|
|
@@ -2163,23 +2379,44 @@ function SignIn({
|
|
|
2163
2379
|
};
|
|
2164
2380
|
}, []);
|
|
2165
2381
|
async function sendLink() {
|
|
2166
|
-
if (!
|
|
2382
|
+
if (!offered.magicLink) {
|
|
2167
2383
|
return;
|
|
2168
2384
|
}
|
|
2169
2385
|
setBusy(true);
|
|
2170
2386
|
setError(null);
|
|
2171
2387
|
try {
|
|
2172
|
-
await client.auth.magicLink.request({ email, redirectUrl:
|
|
2388
|
+
await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
|
|
2173
2389
|
setLinkSent(true);
|
|
2174
2390
|
} catch (cause) {
|
|
2175
2391
|
console.error("[base316] magic link request failed", cause);
|
|
2176
|
-
setError(
|
|
2392
|
+
setError(
|
|
2393
|
+
cause instanceof import_sdk4.Base316Error && cause.code === "INVALID_REQUEST" && cause.message ? cause.message : labels.linkFailed
|
|
2394
|
+
);
|
|
2177
2395
|
} finally {
|
|
2178
2396
|
setBusy(false);
|
|
2179
2397
|
}
|
|
2180
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
|
+
}
|
|
2181
2414
|
async function submit(event) {
|
|
2182
2415
|
event.preventDefault();
|
|
2416
|
+
if (mode === "sso") {
|
|
2417
|
+
leaveForSso();
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2183
2420
|
setBusy(true);
|
|
2184
2421
|
setError(null);
|
|
2185
2422
|
try {
|
|
@@ -2197,7 +2434,7 @@ function SignIn({
|
|
|
2197
2434
|
challengeToken: phoneChallenge.token,
|
|
2198
2435
|
code
|
|
2199
2436
|
});
|
|
2200
|
-
if ((0,
|
|
2437
|
+
if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
|
|
2201
2438
|
setPending(signedIn);
|
|
2202
2439
|
setCode("");
|
|
2203
2440
|
return;
|
|
@@ -2207,7 +2444,7 @@ function SignIn({
|
|
|
2207
2444
|
return;
|
|
2208
2445
|
}
|
|
2209
2446
|
const result = await client.auth.signIn({ email, password });
|
|
2210
|
-
if ((0,
|
|
2447
|
+
if ((0, import_sdk4.needsSecondFactor)(result)) {
|
|
2211
2448
|
setPending(result);
|
|
2212
2449
|
return;
|
|
2213
2450
|
}
|
|
@@ -2216,25 +2453,23 @@ function SignIn({
|
|
|
2216
2453
|
} catch (cause) {
|
|
2217
2454
|
console.error("[base316] sign-in failed", cause);
|
|
2218
2455
|
setError(
|
|
2219
|
-
mode === "phone" ? phoneChallenge ?
|
|
2456
|
+
mode === "phone" ? phoneChallenge ? labels.wrongCode : (
|
|
2220
2457
|
// Why a text could not be sent is worth saying — a number in the
|
|
2221
2458
|
// wrong format, or too many requests — and the server words it
|
|
2222
2459
|
// without saying anything about accounts.
|
|
2223
|
-
cause instanceof Error && cause.message ? cause.message :
|
|
2460
|
+
cause instanceof Error && cause.message ? cause.message : labels.codeFailed
|
|
2224
2461
|
) : (
|
|
2225
2462
|
// An unconfirmed address and a throttle are worth naming; the
|
|
2226
2463
|
// server words both without saying whether an account exists.
|
|
2227
|
-
cause instanceof
|
|
2464
|
+
cause instanceof import_sdk4.Base316Error && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : labels.wrongPassword
|
|
2228
2465
|
)
|
|
2229
2466
|
);
|
|
2230
2467
|
} finally {
|
|
2231
2468
|
setBusy(false);
|
|
2232
2469
|
}
|
|
2233
2470
|
}
|
|
2234
|
-
const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
|
|
2235
|
-
const tabsShown = (magicAvailable || phone) && !pendingChallenge;
|
|
2236
2471
|
if (pending) {
|
|
2237
|
-
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)(
|
|
2238
2473
|
SecondFactorStep,
|
|
2239
2474
|
{
|
|
2240
2475
|
pending,
|
|
@@ -2250,59 +2485,68 @@ function SignIn({
|
|
|
2250
2485
|
) });
|
|
2251
2486
|
}
|
|
2252
2487
|
if (linkSent) {
|
|
2253
|
-
return /* @__PURE__ */ (0,
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2255
|
-
/* @__PURE__ */ (0,
|
|
2256
|
-
|
|
2257
|
-
email,
|
|
2258
|
-
", a sign-in link is on its way. It expires shortly and can be used once."
|
|
2259
|
-
] }),
|
|
2260
|
-
/* @__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)(
|
|
2261
2492
|
"button",
|
|
2262
2493
|
{
|
|
2263
2494
|
type: "button",
|
|
2264
2495
|
className: "b316-button b316-button-secondary",
|
|
2265
2496
|
style: { marginTop: 16 },
|
|
2266
2497
|
onClick: () => setLinkSent(false),
|
|
2267
|
-
children:
|
|
2498
|
+
children: labels.backToSignIn
|
|
2268
2499
|
}
|
|
2269
2500
|
)
|
|
2270
2501
|
] });
|
|
2271
2502
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
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,
|
|
2277
2514
|
{
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
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
|
+
}
|
|
2282
2533
|
}
|
|
2283
2534
|
),
|
|
2284
|
-
|
|
2285
|
-
"button",
|
|
2286
|
-
{
|
|
2287
|
-
type: "button",
|
|
2288
|
-
className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
|
|
2289
|
-
onClick: () => setMode("magic"),
|
|
2290
|
-
children: "Magic link"
|
|
2291
|
-
}
|
|
2292
|
-
) : null,
|
|
2293
|
-
phone ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2294
|
-
"button",
|
|
2295
|
-
{
|
|
2296
|
-
type: "button",
|
|
2297
|
-
className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
|
|
2298
|
-
onClick: () => setMode("phone"),
|
|
2299
|
-
children: "Text message"
|
|
2300
|
-
}
|
|
2301
|
-
) : null
|
|
2535
|
+
hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null
|
|
2302
2536
|
] }) : null,
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
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)(
|
|
2306
2550
|
"input",
|
|
2307
2551
|
{
|
|
2308
2552
|
id: "b316-phone-code",
|
|
@@ -2314,12 +2558,10 @@ function SignIn({
|
|
|
2314
2558
|
required: true
|
|
2315
2559
|
}
|
|
2316
2560
|
),
|
|
2317
|
-
/* @__PURE__ */ (0,
|
|
2318
|
-
|
|
2319
|
-
phoneChallenge.hint,
|
|
2320
|
-
". It expires in ten minutes.",
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "b316-muted", children: [
|
|
2562
|
+
labels.codeSent(phoneChallenge.hint),
|
|
2321
2563
|
" ",
|
|
2322
|
-
/* @__PURE__ */ (0,
|
|
2564
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2323
2565
|
"button",
|
|
2324
2566
|
{
|
|
2325
2567
|
type: "button",
|
|
@@ -2328,13 +2570,13 @@ function SignIn({
|
|
|
2328
2570
|
setPhoneChallenge(null);
|
|
2329
2571
|
setCode("");
|
|
2330
2572
|
},
|
|
2331
|
-
children:
|
|
2573
|
+
children: labels.useDifferentNumber
|
|
2332
2574
|
}
|
|
2333
2575
|
)
|
|
2334
2576
|
] })
|
|
2335
|
-
] }) : /* @__PURE__ */ (0,
|
|
2336
|
-
/* @__PURE__ */ (0,
|
|
2337
|
-
/* @__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)(
|
|
2338
2580
|
"input",
|
|
2339
2581
|
{
|
|
2340
2582
|
id: "b316-phone",
|
|
@@ -2347,11 +2589,11 @@ function SignIn({
|
|
|
2347
2589
|
required: true
|
|
2348
2590
|
}
|
|
2349
2591
|
),
|
|
2350
|
-
/* @__PURE__ */ (0,
|
|
2351
|
-
] }) : /* @__PURE__ */ (0,
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2353
|
-
/* @__PURE__ */ (0,
|
|
2354
|
-
/* @__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)(
|
|
2355
2597
|
"input",
|
|
2356
2598
|
{
|
|
2357
2599
|
id: "b316-email",
|
|
@@ -2359,14 +2601,14 @@ function SignIn({
|
|
|
2359
2601
|
type: "email",
|
|
2360
2602
|
value: email,
|
|
2361
2603
|
onChange: (event) => setEmail(event.target.value),
|
|
2362
|
-
autoComplete: passkeyReady ? "email webauthn" : "email",
|
|
2604
|
+
autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
|
|
2363
2605
|
required: true
|
|
2364
2606
|
}
|
|
2365
2607
|
)
|
|
2366
2608
|
] }),
|
|
2367
|
-
mode === "password" ? /* @__PURE__ */ (0,
|
|
2368
|
-
/* @__PURE__ */ (0,
|
|
2369
|
-
/* @__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)(
|
|
2370
2612
|
"input",
|
|
2371
2613
|
{
|
|
2372
2614
|
id: "b316-password",
|
|
@@ -2379,31 +2621,98 @@ function SignIn({
|
|
|
2379
2621
|
}
|
|
2380
2622
|
)
|
|
2381
2623
|
] }) : null
|
|
2382
|
-
] }),
|
|
2383
|
-
/* @__PURE__ */ (0,
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
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)(
|
|
2387
2640
|
"button",
|
|
2388
2641
|
{
|
|
2389
2642
|
type: "button",
|
|
2390
2643
|
className: "b316-button b316-button-secondary",
|
|
2644
|
+
style: { width: "100%" },
|
|
2391
2645
|
disabled: busy,
|
|
2392
2646
|
onClick: () => {
|
|
2393
2647
|
abortRef.current?.abort();
|
|
2394
2648
|
void signInWithPasskey(false);
|
|
2395
2649
|
},
|
|
2396
|
-
children:
|
|
2650
|
+
children: labels.passkey
|
|
2397
2651
|
}
|
|
2398
|
-
)
|
|
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
|
|
2399
2668
|
] }) : null
|
|
2400
2669
|
] });
|
|
2401
2670
|
}
|
|
2402
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
|
+
|
|
2403
2712
|
// src/SignUp.tsx
|
|
2404
|
-
var
|
|
2405
|
-
var
|
|
2406
|
-
var
|
|
2713
|
+
var import_sdk5 = require("@base316/sdk");
|
|
2714
|
+
var import_react9 = require("react");
|
|
2715
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2407
2716
|
var DEFAULT_SIGN_UP_LABELS = {
|
|
2408
2717
|
name: "Name",
|
|
2409
2718
|
email: "Email",
|
|
@@ -2420,7 +2729,10 @@ var DEFAULT_SIGN_UP_LABELS = {
|
|
|
2420
2729
|
confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
|
|
2421
2730
|
createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
|
|
2422
2731
|
genericError: "We could not create that account. Try again.",
|
|
2423
|
-
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."
|
|
2424
2736
|
};
|
|
2425
2737
|
function describeRules(policy, labels) {
|
|
2426
2738
|
const extras = [
|
|
@@ -2439,30 +2751,35 @@ function SignUp({
|
|
|
2439
2751
|
onJoined,
|
|
2440
2752
|
labels: overrides,
|
|
2441
2753
|
secondFactorLabels,
|
|
2754
|
+
social,
|
|
2755
|
+
socialRedirectUrl,
|
|
2756
|
+
socialState,
|
|
2442
2757
|
className,
|
|
2443
2758
|
style
|
|
2444
2759
|
}) {
|
|
2445
2760
|
const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
|
|
2446
2761
|
const { client, setToken } = useBase316();
|
|
2447
|
-
const
|
|
2448
|
-
const
|
|
2449
|
-
const [
|
|
2450
|
-
const [
|
|
2451
|
-
const [
|
|
2452
|
-
const [
|
|
2453
|
-
const [
|
|
2454
|
-
const [
|
|
2455
|
-
const [
|
|
2456
|
-
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);
|
|
2457
2774
|
const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
|
|
2458
2775
|
const preview = loaded && loaded.token === invitation ? loaded.preview : null;
|
|
2459
|
-
(0,
|
|
2776
|
+
(0, import_react9.useEffect)(() => {
|
|
2460
2777
|
if (suppliedInvitation !== void 0 || typeof window === "undefined") {
|
|
2461
2778
|
return;
|
|
2462
2779
|
}
|
|
2463
2780
|
setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
|
|
2464
2781
|
}, [suppliedInvitation]);
|
|
2465
|
-
(0,
|
|
2782
|
+
(0, import_react9.useEffect)(() => {
|
|
2466
2783
|
if (!invitation) {
|
|
2467
2784
|
return;
|
|
2468
2785
|
}
|
|
@@ -2477,7 +2794,7 @@ function SignUp({
|
|
|
2477
2794
|
cancelled = true;
|
|
2478
2795
|
};
|
|
2479
2796
|
}, [client, invitation]);
|
|
2480
|
-
(0,
|
|
2797
|
+
(0, import_react9.useEffect)(() => {
|
|
2481
2798
|
let cancelled = false;
|
|
2482
2799
|
client.auth.passwordPolicy().then((loaded2) => {
|
|
2483
2800
|
if (!cancelled) {
|
|
@@ -2505,14 +2822,14 @@ function SignUp({
|
|
|
2505
2822
|
} catch (cause) {
|
|
2506
2823
|
console.error("[base316] sign-up failed", cause);
|
|
2507
2824
|
setError(
|
|
2508
|
-
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
|
|
2509
2826
|
);
|
|
2510
2827
|
setBusy(false);
|
|
2511
2828
|
return;
|
|
2512
2829
|
}
|
|
2513
2830
|
try {
|
|
2514
2831
|
const signedIn = await client.auth.signIn({ email, password });
|
|
2515
|
-
if ((0,
|
|
2832
|
+
if ((0, import_sdk5.needsSecondFactor)(signedIn)) {
|
|
2516
2833
|
setPending(signedIn);
|
|
2517
2834
|
return;
|
|
2518
2835
|
}
|
|
@@ -2520,14 +2837,14 @@ function SignUp({
|
|
|
2520
2837
|
onSignedUp?.();
|
|
2521
2838
|
} catch (cause) {
|
|
2522
2839
|
console.error("[base316] sign-in after sign-up failed", cause);
|
|
2523
|
-
if (cause instanceof
|
|
2840
|
+
if (cause instanceof import_sdk5.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
|
|
2524
2841
|
setConfirmEmail(true);
|
|
2525
2842
|
onSignedUp?.();
|
|
2526
2843
|
return;
|
|
2527
2844
|
}
|
|
2528
2845
|
setError(
|
|
2529
2846
|
labels.createdSignInFailed(
|
|
2530
|
-
cause instanceof
|
|
2847
|
+
cause instanceof import_sdk5.Base316Error && cause.message ? cause.message : labels.genericError
|
|
2531
2848
|
)
|
|
2532
2849
|
);
|
|
2533
2850
|
} finally {
|
|
@@ -2535,86 +2852,118 @@ function SignUp({
|
|
|
2535
2852
|
}
|
|
2536
2853
|
}
|
|
2537
2854
|
if (pending) {
|
|
2538
|
-
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 }) });
|
|
2539
2856
|
}
|
|
2540
2857
|
if (confirmEmail) {
|
|
2541
|
-
return /* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2543
|
-
/* @__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) })
|
|
2544
2861
|
] });
|
|
2545
2862
|
}
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
id: "b316-name",
|
|
2555
|
-
className: "b316-input",
|
|
2556
|
-
value: name,
|
|
2557
|
-
onChange: (event) => setName(event.target.value),
|
|
2558
|
-
autoComplete: "name"
|
|
2559
|
-
}
|
|
2560
|
-
)
|
|
2561
|
-
] }),
|
|
2562
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
|
|
2563
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
|
|
2564
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2565
|
-
"input",
|
|
2566
|
-
{
|
|
2567
|
-
id: "b316-signup-email",
|
|
2568
|
-
className: "b316-input",
|
|
2569
|
-
type: "email",
|
|
2570
|
-
value: email,
|
|
2571
|
-
onChange: (event) => setEmail(event.target.value),
|
|
2572
|
-
autoComplete: "email",
|
|
2573
|
-
required: true
|
|
2574
|
-
}
|
|
2575
|
-
)
|
|
2576
|
-
] }),
|
|
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-signup-password", children: labels.password }),
|
|
2579
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2580
|
-
"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,
|
|
2581
2871
|
{
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
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
|
+
}
|
|
2592
2890
|
}
|
|
2593
2891
|
),
|
|
2594
|
-
|
|
2595
|
-
] }),
|
|
2596
|
-
/* @__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
|
|
2597
2946
|
] });
|
|
2598
2947
|
}
|
|
2599
2948
|
|
|
2600
2949
|
// src/UserProfile.tsx
|
|
2601
|
-
var
|
|
2950
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2602
2951
|
function UserProfile({ className, style }) {
|
|
2603
2952
|
const { session, loading, signOut } = useBase316();
|
|
2604
2953
|
if (loading) {
|
|
2605
|
-
return /* @__PURE__ */ (0,
|
|
2954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
2606
2955
|
}
|
|
2607
2956
|
if (!session) {
|
|
2608
|
-
return /* @__PURE__ */ (0,
|
|
2957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
|
|
2609
2958
|
}
|
|
2610
2959
|
const user = session.user ?? {};
|
|
2611
|
-
return /* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2613
|
-
/* @__PURE__ */ (0,
|
|
2614
|
-
user.name && user.email ? /* @__PURE__ */ (0,
|
|
2615
|
-
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
|
|
2616
2965
|
] }),
|
|
2617
|
-
/* @__PURE__ */ (0,
|
|
2966
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2618
2967
|
"button",
|
|
2619
2968
|
{
|
|
2620
2969
|
type: "button",
|
|
@@ -2627,12 +2976,12 @@ function UserProfile({ className, style }) {
|
|
|
2627
2976
|
}
|
|
2628
2977
|
|
|
2629
2978
|
// src/PasskeyManager.tsx
|
|
2630
|
-
var
|
|
2631
|
-
var
|
|
2979
|
+
var import_sdk6 = require("@base316/sdk");
|
|
2980
|
+
var import_react11 = require("react");
|
|
2632
2981
|
|
|
2633
2982
|
// src/confirm.tsx
|
|
2634
|
-
var
|
|
2635
|
-
var
|
|
2983
|
+
var import_react10 = require("react");
|
|
2984
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2636
2985
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
2637
2986
|
function ConfirmButton({
|
|
2638
2987
|
children,
|
|
@@ -2642,9 +2991,9 @@ function ConfirmButton({
|
|
|
2642
2991
|
disabled,
|
|
2643
2992
|
timeoutMs = DEFAULT_TIMEOUT_MS
|
|
2644
2993
|
}) {
|
|
2645
|
-
const [armed, setArmed] = (0,
|
|
2646
|
-
const confirmRef = (0,
|
|
2647
|
-
(0,
|
|
2994
|
+
const [armed, setArmed] = (0, import_react10.useState)(false);
|
|
2995
|
+
const confirmRef = (0, import_react10.useRef)(null);
|
|
2996
|
+
(0, import_react10.useEffect)(() => {
|
|
2648
2997
|
if (!armed) {
|
|
2649
2998
|
return;
|
|
2650
2999
|
}
|
|
@@ -2653,7 +3002,7 @@ function ConfirmButton({
|
|
|
2653
3002
|
return () => clearTimeout(timer);
|
|
2654
3003
|
}, [armed, timeoutMs]);
|
|
2655
3004
|
if (!armed) {
|
|
2656
|
-
return /* @__PURE__ */ (0,
|
|
3005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2657
3006
|
"button",
|
|
2658
3007
|
{
|
|
2659
3008
|
type: "button",
|
|
@@ -2667,8 +3016,8 @@ function ConfirmButton({
|
|
|
2667
3016
|
return (
|
|
2668
3017
|
// No `role="group"`: both buttons already say what they do, and the
|
|
2669
3018
|
// grouping would only repeat the question a screen reader has just read.
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
2671
|
-
/* @__PURE__ */ (0,
|
|
3019
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "b316-confirm", children: [
|
|
3020
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2672
3021
|
"button",
|
|
2673
3022
|
{
|
|
2674
3023
|
ref: confirmRef,
|
|
@@ -2682,7 +3031,7 @@ function ConfirmButton({
|
|
|
2682
3031
|
children: confirmLabel
|
|
2683
3032
|
}
|
|
2684
3033
|
),
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
3034
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2686
3035
|
"button",
|
|
2687
3036
|
{
|
|
2688
3037
|
type: "button",
|
|
@@ -2696,19 +3045,19 @@ function ConfirmButton({
|
|
|
2696
3045
|
}
|
|
2697
3046
|
|
|
2698
3047
|
// src/PasskeyManager.tsx
|
|
2699
|
-
var
|
|
3048
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2700
3049
|
function PasskeyManager({
|
|
2701
3050
|
className,
|
|
2702
3051
|
style,
|
|
2703
3052
|
title = "Passkeys"
|
|
2704
3053
|
}) {
|
|
2705
3054
|
const { client, token, session } = useBase316();
|
|
2706
|
-
const [passkeys, setPasskeys] = (0,
|
|
2707
|
-
const [busy, setBusy] = (0,
|
|
2708
|
-
const [error, setError] = (0,
|
|
2709
|
-
const [name, setName] = (0,
|
|
2710
|
-
const [supported, setSupported] = (0,
|
|
2711
|
-
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 () => {
|
|
2712
3061
|
if (!token) {
|
|
2713
3062
|
return;
|
|
2714
3063
|
}
|
|
@@ -2721,8 +3070,8 @@ function PasskeyManager({
|
|
|
2721
3070
|
setPasskeys(null);
|
|
2722
3071
|
}
|
|
2723
3072
|
}, [client, token]);
|
|
2724
|
-
(0,
|
|
2725
|
-
if (!(0,
|
|
3073
|
+
(0, import_react11.useEffect)(() => {
|
|
3074
|
+
if (!(0, import_sdk6.isPasskeySupported)()) {
|
|
2726
3075
|
return;
|
|
2727
3076
|
}
|
|
2728
3077
|
setSupported(true);
|
|
@@ -2757,18 +3106,18 @@ function PasskeyManager({
|
|
|
2757
3106
|
setError(caught instanceof Error ? caught.message : "That did not work.");
|
|
2758
3107
|
}
|
|
2759
3108
|
};
|
|
2760
|
-
return /* @__PURE__ */ (0,
|
|
2761
|
-
/* @__PURE__ */ (0,
|
|
2762
|
-
/* @__PURE__ */ (0,
|
|
2763
|
-
passkeys === null ? /* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
2766
|
-
/* @__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: [
|
|
2767
3116
|
passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
|
|
2768
3117
|
passkey.backedUp ? "" : " \xB7 this device only"
|
|
2769
3118
|
] })
|
|
2770
3119
|
] }),
|
|
2771
|
-
/* @__PURE__ */ (0,
|
|
3120
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2772
3121
|
ConfirmButton,
|
|
2773
3122
|
{
|
|
2774
3123
|
className: "b316-button b316-button-secondary",
|
|
@@ -2778,9 +3127,9 @@ function PasskeyManager({
|
|
|
2778
3127
|
}
|
|
2779
3128
|
)
|
|
2780
3129
|
] }, passkey.id)) }),
|
|
2781
|
-
error ? /* @__PURE__ */ (0,
|
|
2782
|
-
/* @__PURE__ */ (0,
|
|
2783
|
-
/* @__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)(
|
|
2784
3133
|
"input",
|
|
2785
3134
|
{
|
|
2786
3135
|
className: "b316-input",
|
|
@@ -2789,7 +3138,7 @@ function PasskeyManager({
|
|
|
2789
3138
|
onChange: (event) => setName(event.target.value)
|
|
2790
3139
|
}
|
|
2791
3140
|
),
|
|
2792
|
-
/* @__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" })
|
|
2793
3142
|
] })
|
|
2794
3143
|
] });
|
|
2795
3144
|
}
|
|
@@ -2799,8 +3148,8 @@ function formatDate(value) {
|
|
|
2799
3148
|
}
|
|
2800
3149
|
|
|
2801
3150
|
// src/ActiveSessions.tsx
|
|
2802
|
-
var
|
|
2803
|
-
var
|
|
3151
|
+
var import_react12 = require("react");
|
|
3152
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2804
3153
|
function describeDevice(userAgent) {
|
|
2805
3154
|
if (!userAgent) {
|
|
2806
3155
|
return null;
|
|
@@ -2818,10 +3167,10 @@ function when(value) {
|
|
|
2818
3167
|
}
|
|
2819
3168
|
function ActiveSessions({ onRevoked, className, style }) {
|
|
2820
3169
|
const { client, token } = useBase316();
|
|
2821
|
-
const [sessions, setSessions] = (0,
|
|
2822
|
-
const [error, setError] = (0,
|
|
2823
|
-
const [busy, setBusy] = (0,
|
|
2824
|
-
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)(() => {
|
|
2825
3174
|
if (!token) {
|
|
2826
3175
|
return;
|
|
2827
3176
|
}
|
|
@@ -2832,15 +3181,15 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
2832
3181
|
setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
|
|
2833
3182
|
});
|
|
2834
3183
|
}, [client, token]);
|
|
2835
|
-
(0,
|
|
3184
|
+
(0, import_react12.useEffect)(load, [load]);
|
|
2836
3185
|
if (!token) {
|
|
2837
3186
|
return null;
|
|
2838
3187
|
}
|
|
2839
3188
|
if (error) {
|
|
2840
|
-
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 }) });
|
|
2841
3190
|
}
|
|
2842
3191
|
if (!sessions) {
|
|
2843
|
-
return /* @__PURE__ */ (0,
|
|
3192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
2844
3193
|
}
|
|
2845
3194
|
async function revokeOthers() {
|
|
2846
3195
|
setBusy(true);
|
|
@@ -2854,32 +3203,32 @@ function ActiveSessions({ onRevoked, className, style }) {
|
|
|
2854
3203
|
setBusy(false);
|
|
2855
3204
|
}
|
|
2856
3205
|
}
|
|
2857
|
-
return /* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2860
|
-
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
|
|
2861
3210
|
] }),
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
2863
|
-
/* @__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: [
|
|
2864
3213
|
describeDevice(session.userAgent) ?? "Unknown device",
|
|
2865
3214
|
session.impersonatedBy ? (
|
|
2866
3215
|
// Worth saying loudly: somebody is acting as this account.
|
|
2867
|
-
/* @__PURE__ */ (0,
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "b316-chip", children: " Support access" })
|
|
2868
3217
|
) : null
|
|
2869
3218
|
] }),
|
|
2870
|
-
/* @__PURE__ */ (0,
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
|
|
2871
3220
|
session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
|
|
2872
3221
|
"last used ",
|
|
2873
3222
|
when(session.lastSeenAt)
|
|
2874
3223
|
] })
|
|
2875
3224
|
] }, session.id)) }),
|
|
2876
|
-
sessions.length === 0 ? /* @__PURE__ */ (0,
|
|
3225
|
+
sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
|
|
2877
3226
|
] });
|
|
2878
3227
|
}
|
|
2879
3228
|
|
|
2880
3229
|
// src/DeviceApproval.tsx
|
|
2881
|
-
var
|
|
2882
|
-
var
|
|
3230
|
+
var import_react13 = require("react");
|
|
3231
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2883
3232
|
function DeviceApproval({
|
|
2884
3233
|
userCode = "",
|
|
2885
3234
|
onDecided,
|
|
@@ -2887,11 +3236,11 @@ function DeviceApproval({
|
|
|
2887
3236
|
style
|
|
2888
3237
|
}) {
|
|
2889
3238
|
const { client, token } = useBase316();
|
|
2890
|
-
const [code, setCode] = (0,
|
|
2891
|
-
const [request, setRequest] = (0,
|
|
2892
|
-
const [decided, setDecided] = (0,
|
|
2893
|
-
const [error, setError] = (0,
|
|
2894
|
-
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);
|
|
2895
3244
|
if (!token) {
|
|
2896
3245
|
return null;
|
|
2897
3246
|
}
|
|
@@ -2924,25 +3273,25 @@ function DeviceApproval({
|
|
|
2924
3273
|
}
|
|
2925
3274
|
}
|
|
2926
3275
|
if (decided !== null) {
|
|
2927
|
-
return /* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
2929
|
-
/* @__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." })
|
|
2930
3279
|
] });
|
|
2931
3280
|
}
|
|
2932
3281
|
if (request) {
|
|
2933
|
-
return /* @__PURE__ */ (0,
|
|
2934
|
-
/* @__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: [
|
|
2935
3284
|
"Sign in to ",
|
|
2936
3285
|
request.clientName
|
|
2937
3286
|
] }),
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
3287
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "b316-muted", children: [
|
|
2939
3288
|
request.clientName,
|
|
2940
3289
|
" is asking to sign in as you."
|
|
2941
3290
|
] }),
|
|
2942
|
-
request.scopes.length > 0 ? /* @__PURE__ */ (0,
|
|
2943
|
-
error ? /* @__PURE__ */ (0,
|
|
2944
|
-
/* @__PURE__ */ (0,
|
|
2945
|
-
/* @__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)(
|
|
2946
3295
|
"button",
|
|
2947
3296
|
{
|
|
2948
3297
|
type: "button",
|
|
@@ -2952,7 +3301,7 @@ function DeviceApproval({
|
|
|
2952
3301
|
children: busy ? "Approving\u2026" : "Approve"
|
|
2953
3302
|
}
|
|
2954
3303
|
),
|
|
2955
|
-
/* @__PURE__ */ (0,
|
|
3304
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2956
3305
|
"button",
|
|
2957
3306
|
{
|
|
2958
3307
|
type: "button",
|
|
@@ -2965,11 +3314,11 @@ function DeviceApproval({
|
|
|
2965
3314
|
] })
|
|
2966
3315
|
] });
|
|
2967
3316
|
}
|
|
2968
|
-
return /* @__PURE__ */ (0,
|
|
2969
|
-
/* @__PURE__ */ (0,
|
|
2970
|
-
/* @__PURE__ */ (0,
|
|
2971
|
-
error ? /* @__PURE__ */ (0,
|
|
2972
|
-
/* @__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)(
|
|
2973
3322
|
"input",
|
|
2974
3323
|
{
|
|
2975
3324
|
className: "b316-input",
|
|
@@ -2982,13 +3331,13 @@ function DeviceApproval({
|
|
|
2982
3331
|
"aria-label": "Device code"
|
|
2983
3332
|
}
|
|
2984
3333
|
),
|
|
2985
|
-
/* @__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" })
|
|
2986
3335
|
] });
|
|
2987
3336
|
}
|
|
2988
3337
|
|
|
2989
3338
|
// src/PrivacyControls.tsx
|
|
2990
|
-
var
|
|
2991
|
-
var
|
|
3339
|
+
var import_react14 = require("react");
|
|
3340
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2992
3341
|
function PrivacyControls({
|
|
2993
3342
|
confirmWord = "DELETE",
|
|
2994
3343
|
onErased,
|
|
@@ -2996,10 +3345,10 @@ function PrivacyControls({
|
|
|
2996
3345
|
style
|
|
2997
3346
|
}) {
|
|
2998
3347
|
const { client, token } = useBase316();
|
|
2999
|
-
const [confirming, setConfirming] = (0,
|
|
3000
|
-
const [typed, setTyped] = (0,
|
|
3001
|
-
const [error, setError] = (0,
|
|
3002
|
-
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);
|
|
3003
3352
|
if (!token) {
|
|
3004
3353
|
return null;
|
|
3005
3354
|
}
|
|
@@ -3034,22 +3383,22 @@ function PrivacyControls({
|
|
|
3034
3383
|
setBusy(false);
|
|
3035
3384
|
}
|
|
3036
3385
|
}
|
|
3037
|
-
return /* @__PURE__ */ (0,
|
|
3038
|
-
/* @__PURE__ */ (0,
|
|
3039
|
-
error ? /* @__PURE__ */ (0,
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3041
|
-
/* @__PURE__ */ (0,
|
|
3042
|
-
/* @__PURE__ */ (0,
|
|
3043
|
-
/* @__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." })
|
|
3044
3393
|
] }),
|
|
3045
|
-
/* @__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" })
|
|
3046
3395
|
] }),
|
|
3047
|
-
/* @__PURE__ */ (0,
|
|
3048
|
-
/* @__PURE__ */ (0,
|
|
3049
|
-
/* @__PURE__ */ (0,
|
|
3050
|
-
/* @__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." })
|
|
3051
3400
|
] }),
|
|
3052
|
-
confirming ? null : /* @__PURE__ */ (0,
|
|
3401
|
+
confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3053
3402
|
"button",
|
|
3054
3403
|
{
|
|
3055
3404
|
type: "button",
|
|
@@ -3060,13 +3409,13 @@ function PrivacyControls({
|
|
|
3060
3409
|
}
|
|
3061
3410
|
)
|
|
3062
3411
|
] }),
|
|
3063
|
-
confirming ? /* @__PURE__ */ (0,
|
|
3064
|
-
/* @__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: [
|
|
3065
3414
|
"Type ",
|
|
3066
3415
|
confirmWord,
|
|
3067
3416
|
" to confirm"
|
|
3068
3417
|
] }),
|
|
3069
|
-
/* @__PURE__ */ (0,
|
|
3418
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3070
3419
|
"input",
|
|
3071
3420
|
{
|
|
3072
3421
|
id: "b316-privacy-confirm",
|
|
@@ -3076,8 +3425,8 @@ function PrivacyControls({
|
|
|
3076
3425
|
onChange: (event) => setTyped(event.target.value)
|
|
3077
3426
|
}
|
|
3078
3427
|
),
|
|
3079
|
-
/* @__PURE__ */ (0,
|
|
3080
|
-
/* @__PURE__ */ (0,
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-actions", children: [
|
|
3429
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3081
3430
|
"button",
|
|
3082
3431
|
{
|
|
3083
3432
|
type: "button",
|
|
@@ -3089,7 +3438,7 @@ function PrivacyControls({
|
|
|
3089
3438
|
children: "Cancel"
|
|
3090
3439
|
}
|
|
3091
3440
|
),
|
|
3092
|
-
/* @__PURE__ */ (0,
|
|
3441
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3093
3442
|
"button",
|
|
3094
3443
|
{
|
|
3095
3444
|
type: "button",
|
|
@@ -3105,12 +3454,12 @@ function PrivacyControls({
|
|
|
3105
3454
|
}
|
|
3106
3455
|
|
|
3107
3456
|
// src/TwoFactorManager.tsx
|
|
3108
|
-
var
|
|
3457
|
+
var import_react16 = require("react");
|
|
3109
3458
|
|
|
3110
3459
|
// src/QrCode.tsx
|
|
3111
3460
|
var import_qrcode_generator = __toESM(require("qrcode-generator"));
|
|
3112
|
-
var
|
|
3113
|
-
var
|
|
3461
|
+
var import_react15 = require("react");
|
|
3462
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3114
3463
|
var QUIET_ZONE = 4;
|
|
3115
3464
|
function utf8Binary(value) {
|
|
3116
3465
|
let binary = "";
|
|
@@ -3135,9 +3484,9 @@ function qrPath(value) {
|
|
|
3135
3484
|
return { path, modules };
|
|
3136
3485
|
}
|
|
3137
3486
|
function QrCode({ value, label, size = 180, className }) {
|
|
3138
|
-
const { path, modules } = (0,
|
|
3487
|
+
const { path, modules } = (0, import_react15.useMemo)(() => qrPath(value), [value]);
|
|
3139
3488
|
const extent = modules + QUIET_ZONE * 2;
|
|
3140
|
-
return /* @__PURE__ */ (0,
|
|
3489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3141
3490
|
"svg",
|
|
3142
3491
|
{
|
|
3143
3492
|
className,
|
|
@@ -3149,15 +3498,15 @@ function QrCode({ value, label, size = 180, className }) {
|
|
|
3149
3498
|
shapeRendering: "crispEdges",
|
|
3150
3499
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3151
3500
|
children: [
|
|
3152
|
-
/* @__PURE__ */ (0,
|
|
3153
|
-
/* @__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" })
|
|
3154
3503
|
]
|
|
3155
3504
|
}
|
|
3156
3505
|
);
|
|
3157
3506
|
}
|
|
3158
3507
|
|
|
3159
3508
|
// src/TwoFactorManager.tsx
|
|
3160
|
-
var
|
|
3509
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3161
3510
|
function groupKey(secret) {
|
|
3162
3511
|
return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
|
|
3163
3512
|
}
|
|
@@ -3170,12 +3519,12 @@ function TwoFactorManager({
|
|
|
3170
3519
|
style
|
|
3171
3520
|
}) {
|
|
3172
3521
|
const { client, token } = useBase316();
|
|
3173
|
-
const [stage, setStage] = (0,
|
|
3174
|
-
const [on, setOn] = (0,
|
|
3175
|
-
const [code, setCode] = (0,
|
|
3176
|
-
const [phone, setPhone] = (0,
|
|
3177
|
-
const [error, setError] = (0,
|
|
3178
|
-
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);
|
|
3179
3528
|
if (!token) {
|
|
3180
3529
|
return null;
|
|
3181
3530
|
}
|
|
@@ -3253,17 +3602,17 @@ function TwoFactorManager({
|
|
|
3253
3602
|
setBusy(false);
|
|
3254
3603
|
}
|
|
3255
3604
|
}
|
|
3256
|
-
return /* @__PURE__ */ (0,
|
|
3257
|
-
/* @__PURE__ */ (0,
|
|
3258
|
-
error ? /* @__PURE__ */ (0,
|
|
3259
|
-
stage.name === "saved" ? /* @__PURE__ */ (0,
|
|
3260
|
-
/* @__PURE__ */ (0,
|
|
3261
|
-
/* @__PURE__ */ (0,
|
|
3262
|
-
/* @__PURE__ */ (0,
|
|
3263
|
-
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0,
|
|
3264
|
-
/* @__PURE__ */ (0,
|
|
3265
|
-
/* @__PURE__ */ (0,
|
|
3266
|
-
/* @__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)(
|
|
3267
3616
|
"input",
|
|
3268
3617
|
{
|
|
3269
3618
|
id: "b316-mfa-phone",
|
|
@@ -3275,8 +3624,8 @@ function TwoFactorManager({
|
|
|
3275
3624
|
onChange: (event) => setPhone(event.target.value)
|
|
3276
3625
|
}
|
|
3277
3626
|
),
|
|
3278
|
-
/* @__PURE__ */ (0,
|
|
3279
|
-
/* @__PURE__ */ (0,
|
|
3627
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3628
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3280
3629
|
"button",
|
|
3281
3630
|
{
|
|
3282
3631
|
type: "button",
|
|
@@ -3285,16 +3634,16 @@ function TwoFactorManager({
|
|
|
3285
3634
|
children: "Cancel"
|
|
3286
3635
|
}
|
|
3287
3636
|
),
|
|
3288
|
-
/* @__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" })
|
|
3289
3638
|
] })
|
|
3290
|
-
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0,
|
|
3291
|
-
/* @__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: [
|
|
3292
3641
|
"We sent a code to ",
|
|
3293
3642
|
stage.destinationHint,
|
|
3294
3643
|
". Enter it below to turn this on."
|
|
3295
3644
|
] }),
|
|
3296
|
-
/* @__PURE__ */ (0,
|
|
3297
|
-
/* @__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)(
|
|
3298
3647
|
"input",
|
|
3299
3648
|
{
|
|
3300
3649
|
id: "b316-mfa-code",
|
|
@@ -3305,8 +3654,8 @@ function TwoFactorManager({
|
|
|
3305
3654
|
onChange: (event) => setCode(event.target.value)
|
|
3306
3655
|
}
|
|
3307
3656
|
),
|
|
3308
|
-
/* @__PURE__ */ (0,
|
|
3309
|
-
/* @__PURE__ */ (0,
|
|
3657
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3658
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3310
3659
|
"button",
|
|
3311
3660
|
{
|
|
3312
3661
|
type: "button",
|
|
@@ -3315,7 +3664,7 @@ function TwoFactorManager({
|
|
|
3315
3664
|
children: "Cancel"
|
|
3316
3665
|
}
|
|
3317
3666
|
),
|
|
3318
|
-
/* @__PURE__ */ (0,
|
|
3667
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3319
3668
|
"button",
|
|
3320
3669
|
{
|
|
3321
3670
|
type: "button",
|
|
@@ -3326,9 +3675,9 @@ function TwoFactorManager({
|
|
|
3326
3675
|
}
|
|
3327
3676
|
)
|
|
3328
3677
|
] })
|
|
3329
|
-
] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0,
|
|
3330
|
-
/* @__PURE__ */ (0,
|
|
3331
|
-
/* @__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)(
|
|
3332
3681
|
QrCode,
|
|
3333
3682
|
{
|
|
3334
3683
|
className: "b316-mfa-qr",
|
|
@@ -3336,13 +3685,13 @@ function TwoFactorManager({
|
|
|
3336
3685
|
label: "QR code for your authenticator app"
|
|
3337
3686
|
}
|
|
3338
3687
|
),
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3341
|
-
/* @__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) })
|
|
3342
3691
|
] }),
|
|
3343
|
-
/* @__PURE__ */ (0,
|
|
3344
|
-
/* @__PURE__ */ (0,
|
|
3345
|
-
/* @__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)(
|
|
3346
3695
|
"input",
|
|
3347
3696
|
{
|
|
3348
3697
|
id: "b316-mfa-code",
|
|
@@ -3353,8 +3702,8 @@ function TwoFactorManager({
|
|
|
3353
3702
|
onChange: (event) => setCode(event.target.value)
|
|
3354
3703
|
}
|
|
3355
3704
|
),
|
|
3356
|
-
/* @__PURE__ */ (0,
|
|
3357
|
-
/* @__PURE__ */ (0,
|
|
3705
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
|
|
3706
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3358
3707
|
"button",
|
|
3359
3708
|
{
|
|
3360
3709
|
type: "button",
|
|
@@ -3363,7 +3712,7 @@ function TwoFactorManager({
|
|
|
3363
3712
|
children: "Cancel"
|
|
3364
3713
|
}
|
|
3365
3714
|
),
|
|
3366
|
-
/* @__PURE__ */ (0,
|
|
3715
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3367
3716
|
"button",
|
|
3368
3717
|
{
|
|
3369
3718
|
type: "button",
|
|
@@ -3374,9 +3723,9 @@ function TwoFactorManager({
|
|
|
3374
3723
|
}
|
|
3375
3724
|
)
|
|
3376
3725
|
] })
|
|
3377
|
-
] }) : on ? /* @__PURE__ */ (0,
|
|
3378
|
-
/* @__PURE__ */ (0,
|
|
3379
|
-
/* @__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)(
|
|
3380
3729
|
ConfirmButton,
|
|
3381
3730
|
{
|
|
3382
3731
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3386,11 +3735,11 @@ function TwoFactorManager({
|
|
|
3386
3735
|
children: "Turn off"
|
|
3387
3736
|
}
|
|
3388
3737
|
)
|
|
3389
|
-
] }) : /* @__PURE__ */ (0,
|
|
3390
|
-
/* @__PURE__ */ (0,
|
|
3391
|
-
/* @__PURE__ */ (0,
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3393
|
-
/* @__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)(
|
|
3394
3743
|
"button",
|
|
3395
3744
|
{
|
|
3396
3745
|
type: "button",
|
|
@@ -3400,7 +3749,7 @@ function TwoFactorManager({
|
|
|
3400
3749
|
children: "Email me a code"
|
|
3401
3750
|
}
|
|
3402
3751
|
),
|
|
3403
|
-
allowSms ? /* @__PURE__ */ (0,
|
|
3752
|
+
allowSms ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3404
3753
|
"button",
|
|
3405
3754
|
{
|
|
3406
3755
|
type: "button",
|
|
@@ -3416,14 +3765,14 @@ function TwoFactorManager({
|
|
|
3416
3765
|
}
|
|
3417
3766
|
|
|
3418
3767
|
// src/ForgotPassword.tsx
|
|
3419
|
-
var
|
|
3420
|
-
var
|
|
3768
|
+
var import_react17 = require("react");
|
|
3769
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3421
3770
|
function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
3422
3771
|
const { client } = useBase316();
|
|
3423
|
-
const [email, setEmail] = (0,
|
|
3424
|
-
const [sent, setSent] = (0,
|
|
3425
|
-
const [busy, setBusy] = (0,
|
|
3426
|
-
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);
|
|
3427
3776
|
async function submit(event) {
|
|
3428
3777
|
event.preventDefault();
|
|
3429
3778
|
setBusy(true);
|
|
@@ -3439,22 +3788,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3439
3788
|
}
|
|
3440
3789
|
}
|
|
3441
3790
|
if (sent) {
|
|
3442
|
-
return /* @__PURE__ */ (0,
|
|
3443
|
-
/* @__PURE__ */ (0,
|
|
3444
|
-
/* @__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: [
|
|
3445
3794
|
"If there is an account for ",
|
|
3446
3795
|
email.trim(),
|
|
3447
3796
|
", a link to set a new password is on its way."
|
|
3448
3797
|
] }),
|
|
3449
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3798
|
+
signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3450
3799
|
] });
|
|
3451
3800
|
}
|
|
3452
|
-
return /* @__PURE__ */ (0,
|
|
3453
|
-
/* @__PURE__ */ (0,
|
|
3454
|
-
error ? /* @__PURE__ */ (0,
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
3457
|
-
/* @__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)(
|
|
3458
3807
|
"input",
|
|
3459
3808
|
{
|
|
3460
3809
|
id: "b316-forgot-email",
|
|
@@ -3467,14 +3816,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3467
3816
|
}
|
|
3468
3817
|
)
|
|
3469
3818
|
] }),
|
|
3470
|
-
/* @__PURE__ */ (0,
|
|
3471
|
-
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
|
|
3472
3821
|
] });
|
|
3473
3822
|
}
|
|
3474
3823
|
|
|
3475
3824
|
// src/ResetPassword.tsx
|
|
3476
|
-
var
|
|
3477
|
-
var
|
|
3825
|
+
var import_react18 = require("react");
|
|
3826
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3478
3827
|
function ResetPassword({
|
|
3479
3828
|
token: supplied,
|
|
3480
3829
|
onReset,
|
|
@@ -3483,13 +3832,13 @@ function ResetPassword({
|
|
|
3483
3832
|
style
|
|
3484
3833
|
}) {
|
|
3485
3834
|
const { client } = useBase316();
|
|
3486
|
-
const [token, setToken] = (0,
|
|
3487
|
-
const [password, setPassword] = (0,
|
|
3488
|
-
const [confirmation, setConfirmation] = (0,
|
|
3489
|
-
const [done, setDone] = (0,
|
|
3490
|
-
const [busy, setBusy] = (0,
|
|
3491
|
-
const [error, setError] = (0,
|
|
3492
|
-
(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)(() => {
|
|
3493
3842
|
if (supplied || typeof window === "undefined") {
|
|
3494
3843
|
return;
|
|
3495
3844
|
}
|
|
@@ -3524,24 +3873,24 @@ function ResetPassword({
|
|
|
3524
3873
|
}
|
|
3525
3874
|
}
|
|
3526
3875
|
if (done) {
|
|
3527
|
-
return /* @__PURE__ */ (0,
|
|
3528
|
-
/* @__PURE__ */ (0,
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3530
|
-
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
|
|
3531
3880
|
] });
|
|
3532
3881
|
}
|
|
3533
3882
|
if (!token) {
|
|
3534
|
-
return /* @__PURE__ */ (0,
|
|
3535
|
-
/* @__PURE__ */ (0,
|
|
3536
|
-
/* @__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." })
|
|
3537
3886
|
] });
|
|
3538
3887
|
}
|
|
3539
|
-
return /* @__PURE__ */ (0,
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3541
|
-
error ? /* @__PURE__ */ (0,
|
|
3542
|
-
/* @__PURE__ */ (0,
|
|
3543
|
-
/* @__PURE__ */ (0,
|
|
3544
|
-
/* @__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)(
|
|
3545
3894
|
"input",
|
|
3546
3895
|
{
|
|
3547
3896
|
id: "b316-reset-password",
|
|
@@ -3554,9 +3903,9 @@ function ResetPassword({
|
|
|
3554
3903
|
}
|
|
3555
3904
|
)
|
|
3556
3905
|
] }),
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3558
|
-
/* @__PURE__ */ (0,
|
|
3559
|
-
/* @__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)(
|
|
3560
3909
|
"input",
|
|
3561
3910
|
{
|
|
3562
3911
|
id: "b316-reset-confirm",
|
|
@@ -3569,13 +3918,13 @@ function ResetPassword({
|
|
|
3569
3918
|
}
|
|
3570
3919
|
)
|
|
3571
3920
|
] }),
|
|
3572
|
-
/* @__PURE__ */ (0,
|
|
3921
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
|
|
3573
3922
|
] });
|
|
3574
3923
|
}
|
|
3575
3924
|
|
|
3576
3925
|
// src/VerifyEmail.tsx
|
|
3577
|
-
var
|
|
3578
|
-
var
|
|
3926
|
+
var import_react19 = require("react");
|
|
3927
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3579
3928
|
function VerifyEmail({
|
|
3580
3929
|
token: supplied,
|
|
3581
3930
|
onVerified,
|
|
@@ -3584,9 +3933,9 @@ function VerifyEmail({
|
|
|
3584
3933
|
style
|
|
3585
3934
|
}) {
|
|
3586
3935
|
const { client } = useBase316();
|
|
3587
|
-
const [state, setState] = (0,
|
|
3588
|
-
const spent = (0,
|
|
3589
|
-
(0,
|
|
3936
|
+
const [state, setState] = (0, import_react19.useState)("waiting");
|
|
3937
|
+
const spent = (0, import_react19.useRef)(false);
|
|
3938
|
+
(0, import_react19.useEffect)(() => {
|
|
3590
3939
|
if (spent.current) {
|
|
3591
3940
|
return;
|
|
3592
3941
|
}
|
|
@@ -3612,22 +3961,22 @@ function VerifyEmail({
|
|
|
3612
3961
|
setState("failed");
|
|
3613
3962
|
});
|
|
3614
3963
|
}, [client, supplied, onVerified]);
|
|
3615
|
-
return /* @__PURE__ */ (0,
|
|
3616
|
-
/* @__PURE__ */ (0,
|
|
3617
|
-
/* @__PURE__ */ (0,
|
|
3618
|
-
continueUrl ? /* @__PURE__ */ (0,
|
|
3619
|
-
] }) : state === "failed" ? /* @__PURE__ */ (0,
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3621
|
-
/* @__PURE__ */ (0,
|
|
3622
|
-
] }) : state === "missing" ? /* @__PURE__ */ (0,
|
|
3623
|
-
/* @__PURE__ */ (0,
|
|
3624
|
-
/* @__PURE__ */ (0,
|
|
3625
|
-
] }) : /* @__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" }) });
|
|
3626
3975
|
}
|
|
3627
3976
|
|
|
3628
3977
|
// src/TeamMembers.tsx
|
|
3629
|
-
var
|
|
3630
|
-
var
|
|
3978
|
+
var import_react20 = require("react");
|
|
3979
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3631
3980
|
function TeamMembers({
|
|
3632
3981
|
organizationId,
|
|
3633
3982
|
onInvited,
|
|
@@ -3637,16 +3986,16 @@ function TeamMembers({
|
|
|
3637
3986
|
style
|
|
3638
3987
|
}) {
|
|
3639
3988
|
const { client, token, session } = useBase316();
|
|
3640
|
-
const [teams, setTeams] = (0,
|
|
3641
|
-
const [members, setMembers] = (0,
|
|
3642
|
-
const [invitations, setInvitations] = (0,
|
|
3643
|
-
const [email, setEmail] = (0,
|
|
3644
|
-
const [busy, setBusy] = (0,
|
|
3645
|
-
const [error, setError] = (0,
|
|
3646
|
-
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);
|
|
3647
3996
|
const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
|
|
3648
3997
|
const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
|
|
3649
|
-
const load = (0,
|
|
3998
|
+
const load = (0, import_react20.useCallback)(() => {
|
|
3650
3999
|
if (!token) {
|
|
3651
4000
|
return;
|
|
3652
4001
|
}
|
|
@@ -3654,8 +4003,8 @@ function TeamMembers({
|
|
|
3654
4003
|
(cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
|
|
3655
4004
|
);
|
|
3656
4005
|
}, [client, token]);
|
|
3657
|
-
(0,
|
|
3658
|
-
(0,
|
|
4006
|
+
(0, import_react20.useEffect)(load, [load]);
|
|
4007
|
+
(0, import_react20.useEffect)(() => {
|
|
3659
4008
|
if (!token || !chosen) {
|
|
3660
4009
|
return;
|
|
3661
4010
|
}
|
|
@@ -3686,10 +4035,10 @@ function TeamMembers({
|
|
|
3686
4035
|
return null;
|
|
3687
4036
|
}
|
|
3688
4037
|
if (!teams) {
|
|
3689
|
-
return /* @__PURE__ */ (0,
|
|
4038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
|
|
3690
4039
|
}
|
|
3691
4040
|
if (!chosen) {
|
|
3692
|
-
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." });
|
|
3693
4042
|
}
|
|
3694
4043
|
const canManage = invitations !== null;
|
|
3695
4044
|
async function invite(event) {
|
|
@@ -3739,30 +4088,30 @@ function TeamMembers({
|
|
|
3739
4088
|
setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
|
|
3740
4089
|
}
|
|
3741
4090
|
}
|
|
3742
|
-
return /* @__PURE__ */ (0,
|
|
3743
|
-
/* @__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" }),
|
|
3744
4093
|
team?.inherited ? (
|
|
3745
4094
|
// Not a member of this team, so not in the list below and with nothing
|
|
3746
4095
|
// to leave: access comes from the team that manages it, and ends there.
|
|
3747
|
-
/* @__PURE__ */ (0,
|
|
4096
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
|
|
3748
4097
|
"You have access through",
|
|
3749
4098
|
" ",
|
|
3750
4099
|
teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
|
|
3751
4100
|
"."
|
|
3752
4101
|
] })
|
|
3753
4102
|
) : null,
|
|
3754
|
-
error ? /* @__PURE__ */ (0,
|
|
3755
|
-
/* @__PURE__ */ (0,
|
|
3756
|
-
/* @__PURE__ */ (0,
|
|
3757
|
-
/* @__PURE__ */ (0,
|
|
3758
|
-
/* @__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: [
|
|
3759
4108
|
member.user.email,
|
|
3760
4109
|
member.user.id === session?.userId ? " \xB7 you" : ""
|
|
3761
4110
|
] })
|
|
3762
4111
|
] }),
|
|
3763
|
-
/* @__PURE__ */ (0,
|
|
3764
|
-
/* @__PURE__ */ (0,
|
|
3765
|
-
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)(
|
|
3766
4115
|
ConfirmButton,
|
|
3767
4116
|
{
|
|
3768
4117
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3774,19 +4123,19 @@ function TeamMembers({
|
|
|
3774
4123
|
) : null
|
|
3775
4124
|
] })
|
|
3776
4125
|
] }, member.id)) }),
|
|
3777
|
-
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0,
|
|
3778
|
-
/* @__PURE__ */ (0,
|
|
3779
|
-
/* @__PURE__ */ (0,
|
|
3780
|
-
/* @__PURE__ */ (0,
|
|
3781
|
-
/* @__PURE__ */ (0,
|
|
3782
|
-
/* @__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: [
|
|
3783
4132
|
invitation.role.name,
|
|
3784
4133
|
" \xB7 expires",
|
|
3785
4134
|
" ",
|
|
3786
4135
|
new Date(invitation.expiresAt).toLocaleDateString()
|
|
3787
4136
|
] })
|
|
3788
4137
|
] }),
|
|
3789
|
-
/* @__PURE__ */ (0,
|
|
4138
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3790
4139
|
"button",
|
|
3791
4140
|
{
|
|
3792
4141
|
type: "button",
|
|
@@ -3797,10 +4146,10 @@ function TeamMembers({
|
|
|
3797
4146
|
)
|
|
3798
4147
|
] }, invitation.id)) })
|
|
3799
4148
|
] }) : null,
|
|
3800
|
-
canManage ? /* @__PURE__ */ (0,
|
|
3801
|
-
/* @__PURE__ */ (0,
|
|
3802
|
-
/* @__PURE__ */ (0,
|
|
3803
|
-
/* @__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)(
|
|
3804
4153
|
"input",
|
|
3805
4154
|
{
|
|
3806
4155
|
id: "b316-invite-email",
|
|
@@ -3812,19 +4161,19 @@ function TeamMembers({
|
|
|
3812
4161
|
onChange: (event) => setEmail(event.target.value)
|
|
3813
4162
|
}
|
|
3814
4163
|
),
|
|
3815
|
-
/* @__PURE__ */ (0,
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
|
|
3816
4165
|
] })
|
|
3817
4166
|
] }) : null,
|
|
3818
|
-
copied ? /* @__PURE__ */ (0,
|
|
3819
|
-
/* @__PURE__ */ (0,
|
|
3820
|
-
/* @__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 })
|
|
3821
4170
|
] }) : null
|
|
3822
4171
|
] });
|
|
3823
4172
|
}
|
|
3824
4173
|
|
|
3825
4174
|
// src/AcceptInvitation.tsx
|
|
3826
|
-
var
|
|
3827
|
-
var
|
|
4175
|
+
var import_react21 = require("react");
|
|
4176
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3828
4177
|
function signUpUrlWithInvitation(url, token) {
|
|
3829
4178
|
const [beforeHash, ...hash] = url.split("#");
|
|
3830
4179
|
const base = beforeHash ?? "";
|
|
@@ -3843,18 +4192,18 @@ function AcceptInvitation({
|
|
|
3843
4192
|
style
|
|
3844
4193
|
}) {
|
|
3845
4194
|
const { client, token: session, session: user } = useBase316();
|
|
3846
|
-
const [invitationToken, setInvitationToken] = (0,
|
|
3847
|
-
const [preview, setPreview] = (0,
|
|
3848
|
-
const [state, setState] = (0,
|
|
3849
|
-
const [error, setError] = (0,
|
|
3850
|
-
const [busy, setBusy] = (0,
|
|
3851
|
-
(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)(() => {
|
|
3852
4201
|
if (supplied || typeof window === "undefined") {
|
|
3853
4202
|
return;
|
|
3854
4203
|
}
|
|
3855
4204
|
setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
|
|
3856
4205
|
}, [supplied]);
|
|
3857
|
-
(0,
|
|
4206
|
+
(0, import_react21.useEffect)(() => {
|
|
3858
4207
|
if (!invitationToken) {
|
|
3859
4208
|
setState(supplied === void 0 ? "loading" : "invalid");
|
|
3860
4209
|
return;
|
|
@@ -3891,42 +4240,42 @@ function AcceptInvitation({
|
|
|
3891
4240
|
}
|
|
3892
4241
|
}
|
|
3893
4242
|
if (state === "loading") {
|
|
3894
|
-
return /* @__PURE__ */ (0,
|
|
4243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
3895
4244
|
}
|
|
3896
4245
|
if (state === "invalid") {
|
|
3897
|
-
return /* @__PURE__ */ (0,
|
|
3898
|
-
/* @__PURE__ */ (0,
|
|
3899
|
-
/* @__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." })
|
|
3900
4249
|
] });
|
|
3901
4250
|
}
|
|
3902
4251
|
if (state === "accepted") {
|
|
3903
|
-
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: [
|
|
3904
4253
|
"You have joined ",
|
|
3905
4254
|
preview?.organizationName
|
|
3906
4255
|
] }) });
|
|
3907
4256
|
}
|
|
3908
4257
|
const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
|
|
3909
|
-
return /* @__PURE__ */ (0,
|
|
3910
|
-
/* @__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: [
|
|
3911
4260
|
"Join ",
|
|
3912
4261
|
preview?.organizationName
|
|
3913
4262
|
] }),
|
|
3914
|
-
/* @__PURE__ */ (0,
|
|
4263
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "b316-muted", children: [
|
|
3915
4264
|
"Invited as ",
|
|
3916
4265
|
preview?.email,
|
|
3917
4266
|
" \xB7 ",
|
|
3918
4267
|
preview?.roleName
|
|
3919
4268
|
] }),
|
|
3920
|
-
error ? /* @__PURE__ */ (0,
|
|
3921
|
-
!session ? /* @__PURE__ */ (0,
|
|
3922
|
-
/* @__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: [
|
|
3923
4272
|
"Sign in as ",
|
|
3924
4273
|
preview?.email,
|
|
3925
4274
|
" to accept."
|
|
3926
4275
|
] }),
|
|
3927
|
-
/* @__PURE__ */ (0,
|
|
3928
|
-
signInUrl ? /* @__PURE__ */ (0,
|
|
3929
|
-
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)(
|
|
3930
4279
|
"a",
|
|
3931
4280
|
{
|
|
3932
4281
|
className: "b316-button-link",
|
|
@@ -3939,20 +4288,20 @@ function AcceptInvitation({
|
|
|
3939
4288
|
// Said before they press anything. The server refuses this, but
|
|
3940
4289
|
// finding out after a click reads as a broken invitation rather than
|
|
3941
4290
|
// as being signed in as the wrong person.
|
|
3942
|
-
/* @__PURE__ */ (0,
|
|
4291
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
|
|
3943
4292
|
"You are signed in as ",
|
|
3944
4293
|
user?.user.email,
|
|
3945
4294
|
". This invitation was sent to ",
|
|
3946
4295
|
preview?.email,
|
|
3947
4296
|
" \u2014 sign in as that address to accept it."
|
|
3948
4297
|
] })
|
|
3949
|
-
) : /* @__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}` })
|
|
3950
4299
|
] });
|
|
3951
4300
|
}
|
|
3952
4301
|
|
|
3953
4302
|
// src/PayInvoice.tsx
|
|
3954
|
-
var
|
|
3955
|
-
var
|
|
4303
|
+
var import_react22 = require("react");
|
|
4304
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3956
4305
|
var STRIPE_SRC = "https://js.stripe.com/v3/";
|
|
3957
4306
|
function loadStripeScript() {
|
|
3958
4307
|
if (typeof window === "undefined") {
|
|
@@ -3984,14 +4333,14 @@ function PayInvoice({
|
|
|
3984
4333
|
style
|
|
3985
4334
|
}) {
|
|
3986
4335
|
const { client } = useBase316();
|
|
3987
|
-
const mountRef = (0,
|
|
3988
|
-
const stripeRef = (0,
|
|
3989
|
-
const elementsRef = (0,
|
|
3990
|
-
const [ready, setReady] = (0,
|
|
3991
|
-
const [paying, setPaying] = (0,
|
|
3992
|
-
const [done, setDone] = (0,
|
|
3993
|
-
const [error, setError] = (0,
|
|
3994
|
-
(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)(() => {
|
|
3995
4344
|
let cancelled = false;
|
|
3996
4345
|
async function start() {
|
|
3997
4346
|
const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
|
|
@@ -4044,17 +4393,17 @@ function PayInvoice({
|
|
|
4044
4393
|
onPaid?.();
|
|
4045
4394
|
};
|
|
4046
4395
|
if (done) {
|
|
4047
|
-
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." }) });
|
|
4048
4397
|
}
|
|
4049
|
-
return /* @__PURE__ */ (0,
|
|
4050
|
-
error ? /* @__PURE__ */ (0,
|
|
4051
|
-
/* @__PURE__ */ (0,
|
|
4052
|
-
/* @__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" })
|
|
4053
4402
|
] });
|
|
4054
4403
|
}
|
|
4055
4404
|
|
|
4056
4405
|
// src/usePaymentLink.ts
|
|
4057
|
-
var
|
|
4406
|
+
var import_react23 = require("react");
|
|
4058
4407
|
function usePaymentLink({
|
|
4059
4408
|
token,
|
|
4060
4409
|
environmentId,
|
|
@@ -4062,10 +4411,10 @@ function usePaymentLink({
|
|
|
4062
4411
|
onPaid
|
|
4063
4412
|
}) {
|
|
4064
4413
|
const { client } = useBase316();
|
|
4065
|
-
const [status2, setStatus] = (0,
|
|
4066
|
-
const onPaidRef = (0,
|
|
4414
|
+
const [status2, setStatus] = (0, import_react23.useState)({ state: "loading" });
|
|
4415
|
+
const onPaidRef = (0, import_react23.useRef)(onPaid);
|
|
4067
4416
|
onPaidRef.current = onPaid;
|
|
4068
|
-
(0,
|
|
4417
|
+
(0, import_react23.useEffect)(() => {
|
|
4069
4418
|
let stopped = false;
|
|
4070
4419
|
let timer;
|
|
4071
4420
|
const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
|
|
@@ -4114,23 +4463,23 @@ function usePaymentLink({
|
|
|
4114
4463
|
}
|
|
4115
4464
|
|
|
4116
4465
|
// src/PricingTable.tsx
|
|
4117
|
-
var
|
|
4466
|
+
var import_react25 = require("react");
|
|
4118
4467
|
|
|
4119
4468
|
// src/usePlans.ts
|
|
4120
|
-
var
|
|
4469
|
+
var import_react24 = require("react");
|
|
4121
4470
|
var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
|
|
4122
4471
|
function usePlans(options = {}) {
|
|
4123
4472
|
const { client, token } = useBase316();
|
|
4124
|
-
const [plans, setPlans] = (0,
|
|
4125
|
-
const [error, setError] = (0,
|
|
4126
|
-
const [busyPlanVersionId, setBusy] = (0,
|
|
4127
|
-
const [lastError, setLastError] = (0,
|
|
4128
|
-
const [ownPlanVersionId, setOwnPlanVersionId] = (0,
|
|
4129
|
-
const [managedBy, setManagedBy] = (0,
|
|
4130
|
-
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);
|
|
4131
4480
|
const supplied = options.currentPlanVersionId;
|
|
4132
4481
|
const discover = supplied === void 0;
|
|
4133
|
-
(0,
|
|
4482
|
+
(0, import_react24.useEffect)(() => {
|
|
4134
4483
|
let cancelled = false;
|
|
4135
4484
|
client.billing.plans().then((result) => {
|
|
4136
4485
|
if (!cancelled) {
|
|
@@ -4146,7 +4495,7 @@ function usePlans(options = {}) {
|
|
|
4146
4495
|
cancelled = true;
|
|
4147
4496
|
};
|
|
4148
4497
|
}, [client, reloadCount]);
|
|
4149
|
-
(0,
|
|
4498
|
+
(0, import_react24.useEffect)(() => {
|
|
4150
4499
|
if (!token) {
|
|
4151
4500
|
return;
|
|
4152
4501
|
}
|
|
@@ -4163,11 +4512,11 @@ function usePlans(options = {}) {
|
|
|
4163
4512
|
cancelled = true;
|
|
4164
4513
|
};
|
|
4165
4514
|
}, [client, token, discover, reloadCount]);
|
|
4166
|
-
const reload = (0,
|
|
4515
|
+
const reload = (0, import_react24.useCallback)(() => {
|
|
4167
4516
|
setError(false);
|
|
4168
4517
|
setReloadCount((count) => count + 1);
|
|
4169
4518
|
}, []);
|
|
4170
|
-
const selectPlan = (0,
|
|
4519
|
+
const selectPlan = (0, import_react24.useCallback)(
|
|
4171
4520
|
async (plan) => {
|
|
4172
4521
|
setLastError(null);
|
|
4173
4522
|
if (managedBy) {
|
|
@@ -4235,7 +4584,7 @@ function usePlans(options = {}) {
|
|
|
4235
4584
|
}
|
|
4236
4585
|
|
|
4237
4586
|
// src/PricingTable.tsx
|
|
4238
|
-
var
|
|
4587
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
4239
4588
|
function formatAmount(amount, currency) {
|
|
4240
4589
|
if (amount === null) return "Free";
|
|
4241
4590
|
const value = Number(amount);
|
|
@@ -4284,7 +4633,7 @@ function PricingTable({
|
|
|
4284
4633
|
managedBy,
|
|
4285
4634
|
selectPlan
|
|
4286
4635
|
} = usePlans({ currentPlanVersionId });
|
|
4287
|
-
const [scheduled, setScheduled] = (0,
|
|
4636
|
+
const [scheduled, setScheduled] = (0, import_react25.useState)(null);
|
|
4288
4637
|
async function choose(plan) {
|
|
4289
4638
|
if (onSelectPlan) {
|
|
4290
4639
|
await onSelectPlan(plan.planVersionId, plan);
|
|
@@ -4301,50 +4650,50 @@ function PricingTable({
|
|
|
4301
4650
|
}
|
|
4302
4651
|
}
|
|
4303
4652
|
if (error) {
|
|
4304
|
-
return /* @__PURE__ */ (0,
|
|
4653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
|
|
4305
4654
|
}
|
|
4306
4655
|
if (!plans) {
|
|
4307
|
-
return /* @__PURE__ */ (0,
|
|
4656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
|
|
4308
4657
|
}
|
|
4309
4658
|
if (plans.length === 0) {
|
|
4310
|
-
return /* @__PURE__ */ (0,
|
|
4659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
|
|
4311
4660
|
}
|
|
4312
4661
|
const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
|
|
4313
4662
|
const anyDescription = plans.some((plan) => Boolean(plan.description));
|
|
4314
4663
|
const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
|
|
4315
|
-
return /* @__PURE__ */ (0,
|
|
4664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cls("b316-plans", className), style, children: [
|
|
4316
4665
|
managedBy ? (
|
|
4317
4666
|
// A client company's plan comes from the firm that runs it. The table
|
|
4318
4667
|
// still shows what is on offer, with the current plan marked, but
|
|
4319
4668
|
// nothing here can be bought: it would grant this account nothing.
|
|
4320
|
-
/* @__PURE__ */ (0,
|
|
4669
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
|
|
4321
4670
|
"Your plan is provided by ",
|
|
4322
4671
|
managedBy.name ?? "the organization that manages your account",
|
|
4323
4672
|
". Ask them to change it."
|
|
4324
4673
|
] })
|
|
4325
|
-
) : 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,
|
|
4326
4675
|
plans.map((plan) => {
|
|
4327
4676
|
const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
|
|
4328
4677
|
const isCurrent = current === plan.planVersionId;
|
|
4329
4678
|
const featured = featuredPlanKey === plan.key;
|
|
4330
|
-
return /* @__PURE__ */ (0,
|
|
4679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
4331
4680
|
"div",
|
|
4332
4681
|
{
|
|
4333
4682
|
className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
|
|
4334
4683
|
children: [
|
|
4335
|
-
/* @__PURE__ */ (0,
|
|
4336
|
-
anyFeatured ? /* @__PURE__ */ (0,
|
|
4337
|
-
/* @__PURE__ */ (0,
|
|
4338
|
-
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
|
|
4339
4688
|
] }),
|
|
4340
|
-
/* @__PURE__ */ (0,
|
|
4341
|
-
/* @__PURE__ */ (0,
|
|
4342
|
-
/* @__PURE__ */ (0,
|
|
4343
|
-
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
|
|
4344
4693
|
] }),
|
|
4345
|
-
/* @__PURE__ */ (0,
|
|
4346
|
-
/* @__PURE__ */ (0,
|
|
4347
|
-
/* @__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" : (
|
|
4348
4697
|
// A usage price on the feature makes the limit an
|
|
4349
4698
|
// allowance billed past, not a ceiling — the same
|
|
4350
4699
|
// rule `check()` applies (any non-FLAT price).
|
|
@@ -4353,7 +4702,7 @@ function PricingTable({
|
|
|
4353
4702
|
) ? `${entitlement.limit} included` : entitlement.limit
|
|
4354
4703
|
) })
|
|
4355
4704
|
] }, entitlement.featureId)) }),
|
|
4356
|
-
/* @__PURE__ */ (0,
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4357
4706
|
"button",
|
|
4358
4707
|
{
|
|
4359
4708
|
type: "button",
|
|
@@ -4374,12 +4723,12 @@ function PricingTable({
|
|
|
4374
4723
|
}
|
|
4375
4724
|
|
|
4376
4725
|
// src/DataTable.tsx
|
|
4377
|
-
var
|
|
4378
|
-
var
|
|
4726
|
+
var import_sdk9 = require("@base316/sdk");
|
|
4727
|
+
var import_react29 = require("react");
|
|
4379
4728
|
|
|
4380
4729
|
// src/fields.tsx
|
|
4381
|
-
var
|
|
4382
|
-
var
|
|
4730
|
+
var import_sdk7 = require("@base316/sdk");
|
|
4731
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4383
4732
|
function formatNumber(value, fraction = 0) {
|
|
4384
4733
|
const number = Number(value);
|
|
4385
4734
|
return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
|
|
@@ -4401,10 +4750,10 @@ function formatDuration(value) {
|
|
|
4401
4750
|
}
|
|
4402
4751
|
function FieldCell({ value, field, related }) {
|
|
4403
4752
|
if (field.type === "RELATION") {
|
|
4404
|
-
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");
|
|
4405
4754
|
}
|
|
4406
4755
|
if (value === null || value === void 0 || value === "") {
|
|
4407
|
-
return /* @__PURE__ */ (0,
|
|
4756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2014" });
|
|
4408
4757
|
}
|
|
4409
4758
|
switch (field.type) {
|
|
4410
4759
|
case "BOOLEAN":
|
|
@@ -4417,9 +4766,9 @@ function FieldCell({ value, field, related }) {
|
|
|
4417
4766
|
return formatDuration(value);
|
|
4418
4767
|
case "RATING": {
|
|
4419
4768
|
const stars = Math.round(Number(value));
|
|
4420
|
-
return /* @__PURE__ */ (0,
|
|
4769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
|
|
4421
4770
|
"\u2605".repeat(stars),
|
|
4422
|
-
/* @__PURE__ */ (0,
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
|
|
4423
4772
|
] });
|
|
4424
4773
|
}
|
|
4425
4774
|
case "DATE":
|
|
@@ -4427,17 +4776,17 @@ function FieldCell({ value, field, related }) {
|
|
|
4427
4776
|
case "DATETIME":
|
|
4428
4777
|
return new Date(String(value)).toLocaleString();
|
|
4429
4778
|
case "SELECT":
|
|
4430
|
-
return /* @__PURE__ */ (0,
|
|
4779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(value) });
|
|
4431
4780
|
case "MULTISELECT":
|
|
4432
|
-
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))) });
|
|
4433
4782
|
case "URL":
|
|
4434
|
-
return /* @__PURE__ */ (0,
|
|
4783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
|
|
4435
4784
|
case "EMAIL":
|
|
4436
|
-
return /* @__PURE__ */ (0,
|
|
4785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
|
|
4437
4786
|
case "PHONE":
|
|
4438
|
-
return /* @__PURE__ */ (0,
|
|
4787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
|
|
4439
4788
|
case "ADDRESS":
|
|
4440
|
-
return (0,
|
|
4789
|
+
return (0, import_sdk7.formatAddress)(value);
|
|
4441
4790
|
case "ATTACHMENT": {
|
|
4442
4791
|
const files = Array.isArray(value) ? value : [value];
|
|
4443
4792
|
return `${files.length} file${files.length === 1 ? "" : "s"}`;
|
|
@@ -4447,13 +4796,13 @@ function FieldCell({ value, field, related }) {
|
|
|
4447
4796
|
return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
|
|
4448
4797
|
}
|
|
4449
4798
|
case "JSON":
|
|
4450
|
-
return /* @__PURE__ */ (0,
|
|
4799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
|
|
4451
4800
|
default:
|
|
4452
4801
|
return String(value);
|
|
4453
4802
|
}
|
|
4454
4803
|
}
|
|
4455
4804
|
function FieldInput({ value, field, onChange, error, disabled }) {
|
|
4456
|
-
if ((0,
|
|
4805
|
+
if ((0, import_sdk7.specFor)(field).computed) {
|
|
4457
4806
|
return null;
|
|
4458
4807
|
}
|
|
4459
4808
|
const id = `b316-field-${field.key}`;
|
|
@@ -4468,7 +4817,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4468
4817
|
function control() {
|
|
4469
4818
|
switch (field.type) {
|
|
4470
4819
|
case "LONGTEXT":
|
|
4471
|
-
return /* @__PURE__ */ (0,
|
|
4820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4472
4821
|
"textarea",
|
|
4473
4822
|
{
|
|
4474
4823
|
...common,
|
|
@@ -4478,7 +4827,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4478
4827
|
}
|
|
4479
4828
|
);
|
|
4480
4829
|
case "BOOLEAN":
|
|
4481
|
-
return /* @__PURE__ */ (0,
|
|
4830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4482
4831
|
"input",
|
|
4483
4832
|
{
|
|
4484
4833
|
...common,
|
|
@@ -4489,22 +4838,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4489
4838
|
}
|
|
4490
4839
|
);
|
|
4491
4840
|
case "SELECT":
|
|
4492
|
-
return /* @__PURE__ */ (0,
|
|
4841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
4493
4842
|
"select",
|
|
4494
4843
|
{
|
|
4495
4844
|
...common,
|
|
4496
4845
|
value: value === null || value === void 0 ? "" : String(value),
|
|
4497
4846
|
onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
|
|
4498
4847
|
children: [
|
|
4499
|
-
field.required ? null : /* @__PURE__ */ (0,
|
|
4500
|
-
(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))
|
|
4501
4850
|
]
|
|
4502
4851
|
}
|
|
4503
4852
|
);
|
|
4504
4853
|
case "MULTISELECT": {
|
|
4505
4854
|
const selected = new Set(Array.isArray(value) ? value.map(String) : []);
|
|
4506
|
-
return /* @__PURE__ */ (0,
|
|
4507
|
-
/* @__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)(
|
|
4508
4857
|
"input",
|
|
4509
4858
|
{
|
|
4510
4859
|
type: "checkbox",
|
|
@@ -4527,7 +4876,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4527
4876
|
case "NUMBER":
|
|
4528
4877
|
case "MONEY":
|
|
4529
4878
|
case "PERCENT":
|
|
4530
|
-
return /* @__PURE__ */ (0,
|
|
4879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4531
4880
|
"input",
|
|
4532
4881
|
{
|
|
4533
4882
|
...common,
|
|
@@ -4538,7 +4887,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4538
4887
|
}
|
|
4539
4888
|
);
|
|
4540
4889
|
case "RATING":
|
|
4541
|
-
return /* @__PURE__ */ (0,
|
|
4890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4542
4891
|
"input",
|
|
4543
4892
|
{
|
|
4544
4893
|
...common,
|
|
@@ -4552,8 +4901,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4552
4901
|
);
|
|
4553
4902
|
case "DURATION": {
|
|
4554
4903
|
const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
|
|
4555
|
-
return /* @__PURE__ */ (0,
|
|
4556
|
-
/* @__PURE__ */ (0,
|
|
4904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-suffixed", children: [
|
|
4905
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4557
4906
|
"input",
|
|
4558
4907
|
{
|
|
4559
4908
|
...common,
|
|
@@ -4563,11 +4912,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4563
4912
|
onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
|
|
4564
4913
|
}
|
|
4565
4914
|
),
|
|
4566
|
-
/* @__PURE__ */ (0,
|
|
4915
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "minutes" })
|
|
4567
4916
|
] });
|
|
4568
4917
|
}
|
|
4569
4918
|
case "DATE":
|
|
4570
|
-
return /* @__PURE__ */ (0,
|
|
4919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4571
4920
|
"input",
|
|
4572
4921
|
{
|
|
4573
4922
|
...common,
|
|
@@ -4577,7 +4926,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4577
4926
|
}
|
|
4578
4927
|
);
|
|
4579
4928
|
case "DATETIME":
|
|
4580
|
-
return /* @__PURE__ */ (0,
|
|
4929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4581
4930
|
"input",
|
|
4582
4931
|
{
|
|
4583
4932
|
...common,
|
|
@@ -4590,7 +4939,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4590
4939
|
);
|
|
4591
4940
|
case "ADDRESS": {
|
|
4592
4941
|
const address = value ?? {};
|
|
4593
|
-
const part = (key, label) => /* @__PURE__ */ (0,
|
|
4942
|
+
const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4594
4943
|
"input",
|
|
4595
4944
|
{
|
|
4596
4945
|
className: "b316-input",
|
|
@@ -4602,7 +4951,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4602
4951
|
},
|
|
4603
4952
|
key
|
|
4604
4953
|
);
|
|
4605
|
-
return /* @__PURE__ */ (0,
|
|
4954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-address", children: [
|
|
4606
4955
|
part("line1", "Address line 1"),
|
|
4607
4956
|
part("line2", "Address line 2"),
|
|
4608
4957
|
part("city", "City"),
|
|
@@ -4612,7 +4961,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4612
4961
|
] });
|
|
4613
4962
|
}
|
|
4614
4963
|
case "EMAIL":
|
|
4615
|
-
return /* @__PURE__ */ (0,
|
|
4964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4616
4965
|
"input",
|
|
4617
4966
|
{
|
|
4618
4967
|
...common,
|
|
@@ -4622,7 +4971,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4622
4971
|
}
|
|
4623
4972
|
);
|
|
4624
4973
|
case "URL":
|
|
4625
|
-
return /* @__PURE__ */ (0,
|
|
4974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4626
4975
|
"input",
|
|
4627
4976
|
{
|
|
4628
4977
|
...common,
|
|
@@ -4632,7 +4981,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4632
4981
|
}
|
|
4633
4982
|
);
|
|
4634
4983
|
case "PHONE":
|
|
4635
|
-
return /* @__PURE__ */ (0,
|
|
4984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4636
4985
|
"input",
|
|
4637
4986
|
{
|
|
4638
4987
|
...common,
|
|
@@ -4642,7 +4991,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4642
4991
|
}
|
|
4643
4992
|
);
|
|
4644
4993
|
default:
|
|
4645
|
-
return /* @__PURE__ */ (0,
|
|
4994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4646
4995
|
"input",
|
|
4647
4996
|
{
|
|
4648
4997
|
...common,
|
|
@@ -4653,24 +5002,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4653
5002
|
);
|
|
4654
5003
|
}
|
|
4655
5004
|
}
|
|
4656
|
-
return /* @__PURE__ */ (0,
|
|
4657
|
-
/* @__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: [
|
|
4658
5007
|
field.label,
|
|
4659
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5008
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4660
5009
|
] }),
|
|
4661
5010
|
control(),
|
|
4662
|
-
field.description ? /* @__PURE__ */ (0,
|
|
4663
|
-
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
|
|
4664
5013
|
] });
|
|
4665
5014
|
}
|
|
4666
5015
|
|
|
4667
5016
|
// src/RecordForm.tsx
|
|
4668
|
-
var
|
|
4669
|
-
var
|
|
5017
|
+
var import_sdk8 = require("@base316/sdk");
|
|
5018
|
+
var import_react28 = require("react");
|
|
4670
5019
|
|
|
4671
5020
|
// src/RelationPicker.tsx
|
|
4672
|
-
var
|
|
4673
|
-
var
|
|
5021
|
+
var import_react26 = require("react");
|
|
5022
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
4674
5023
|
function RelationPicker({
|
|
4675
5024
|
field,
|
|
4676
5025
|
value,
|
|
@@ -4680,13 +5029,13 @@ function RelationPicker({
|
|
|
4680
5029
|
tenant
|
|
4681
5030
|
}) {
|
|
4682
5031
|
const { client, token } = useBase316();
|
|
4683
|
-
const [query, setQuery] = (0,
|
|
4684
|
-
const [results, setResults] = (0,
|
|
4685
|
-
const [chosenTitle, setChosenTitle] = (0,
|
|
4686
|
-
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);
|
|
4687
5036
|
const id = `b316-field-${field.key}`;
|
|
4688
|
-
const box = (0,
|
|
4689
|
-
(0,
|
|
5037
|
+
const box = (0, import_react26.useRef)(null);
|
|
5038
|
+
(0, import_react26.useEffect)(() => {
|
|
4690
5039
|
if (!token || !value || !field.relationTo) {
|
|
4691
5040
|
setChosenTitle(null);
|
|
4692
5041
|
return;
|
|
@@ -4701,7 +5050,7 @@ function RelationPicker({
|
|
|
4701
5050
|
cancelled = true;
|
|
4702
5051
|
};
|
|
4703
5052
|
}, [client, token, value, field.relationTo, tenant]);
|
|
4704
|
-
(0,
|
|
5053
|
+
(0, import_react26.useEffect)(() => {
|
|
4705
5054
|
if (!token || !field.relationTo || !open) {
|
|
4706
5055
|
return;
|
|
4707
5056
|
}
|
|
@@ -4727,7 +5076,7 @@ function RelationPicker({
|
|
|
4727
5076
|
clearTimeout(timer);
|
|
4728
5077
|
};
|
|
4729
5078
|
}, [client, token, field.relationTo, query, open, tenant]);
|
|
4730
|
-
(0,
|
|
5079
|
+
(0, import_react26.useEffect)(() => {
|
|
4731
5080
|
if (!open || typeof document === "undefined") {
|
|
4732
5081
|
return;
|
|
4733
5082
|
}
|
|
@@ -4741,14 +5090,14 @@ function RelationPicker({
|
|
|
4741
5090
|
document.removeEventListener("mousedown", onDocumentClick);
|
|
4742
5091
|
};
|
|
4743
5092
|
}, [open]);
|
|
4744
|
-
return /* @__PURE__ */ (0,
|
|
4745
|
-
/* @__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: [
|
|
4746
5095
|
field.label,
|
|
4747
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5096
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4748
5097
|
] }),
|
|
4749
|
-
value && !open ? /* @__PURE__ */ (0,
|
|
4750
|
-
/* @__PURE__ */ (0,
|
|
4751
|
-
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)(
|
|
4752
5101
|
"button",
|
|
4753
5102
|
{
|
|
4754
5103
|
type: "button",
|
|
@@ -4760,7 +5109,7 @@ function RelationPicker({
|
|
|
4760
5109
|
children: "Change"
|
|
4761
5110
|
}
|
|
4762
5111
|
),
|
|
4763
|
-
disabled || field.required ? null : /* @__PURE__ */ (0,
|
|
5112
|
+
disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4764
5113
|
"button",
|
|
4765
5114
|
{
|
|
4766
5115
|
type: "button",
|
|
@@ -4770,8 +5119,8 @@ function RelationPicker({
|
|
|
4770
5119
|
children: "Clear"
|
|
4771
5120
|
}
|
|
4772
5121
|
)
|
|
4773
|
-
] }) : /* @__PURE__ */ (0,
|
|
4774
|
-
/* @__PURE__ */ (0,
|
|
5122
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5123
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4775
5124
|
"input",
|
|
4776
5125
|
{
|
|
4777
5126
|
id,
|
|
@@ -4792,7 +5141,7 @@ function RelationPicker({
|
|
|
4792
5141
|
}
|
|
4793
5142
|
}
|
|
4794
5143
|
),
|
|
4795
|
-
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)(
|
|
4796
5145
|
"button",
|
|
4797
5146
|
{
|
|
4798
5147
|
type: "button",
|
|
@@ -4808,13 +5157,13 @@ function RelationPicker({
|
|
|
4808
5157
|
}
|
|
4809
5158
|
) }, result.id)) }) : null
|
|
4810
5159
|
] }),
|
|
4811
|
-
field.description ? /* @__PURE__ */ (0,
|
|
4812
|
-
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
|
|
4813
5162
|
] });
|
|
4814
5163
|
}
|
|
4815
5164
|
|
|
4816
5165
|
// src/useCollection.ts
|
|
4817
|
-
var
|
|
5166
|
+
var import_react27 = require("react");
|
|
4818
5167
|
function fieldErrorFrom(cause) {
|
|
4819
5168
|
const param = cause?.param;
|
|
4820
5169
|
const message = cause instanceof Error ? cause.message : "That value was not accepted.";
|
|
@@ -4822,24 +5171,24 @@ function fieldErrorFrom(cause) {
|
|
|
4822
5171
|
}
|
|
4823
5172
|
function useCollection(collection, options = {}) {
|
|
4824
5173
|
const { client, token } = useBase316();
|
|
4825
|
-
const [schema, setSchema] = (0,
|
|
4826
|
-
const [records, setRecords] = (0,
|
|
4827
|
-
const [error, setError] = (0,
|
|
4828
|
-
const [loading, setLoading] = (0,
|
|
4829
|
-
const [total, setTotal] = (0,
|
|
4830
|
-
const [cursor, setCursor] = (0,
|
|
4831
|
-
const [reloadCount, setReloadCount] = (0,
|
|
4832
|
-
const [search, setSearch] = (0,
|
|
4833
|
-
const [filters, setFilters] = (0,
|
|
4834
|
-
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)(
|
|
4835
5184
|
options.sort ?? null
|
|
4836
5185
|
);
|
|
4837
|
-
const [fieldErrors, setFieldErrors] = (0,
|
|
4838
|
-
const [saving, setSaving] = (0,
|
|
5186
|
+
const [fieldErrors, setFieldErrors] = (0, import_react27.useState)({});
|
|
5187
|
+
const [saving, setSaving] = (0, import_react27.useState)(false);
|
|
4839
5188
|
const { tenant, limit, recordId } = options;
|
|
4840
5189
|
const fixedFilters = JSON.stringify(options.filters ?? []);
|
|
4841
|
-
const scope = (0,
|
|
4842
|
-
(0,
|
|
5190
|
+
const scope = (0, import_react27.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
|
|
5191
|
+
(0, import_react27.useEffect)(() => {
|
|
4843
5192
|
if (!token) {
|
|
4844
5193
|
return;
|
|
4845
5194
|
}
|
|
@@ -4858,7 +5207,7 @@ function useCollection(collection, options = {}) {
|
|
|
4858
5207
|
cancelled = true;
|
|
4859
5208
|
};
|
|
4860
5209
|
}, [client, token, collection, scope]);
|
|
4861
|
-
(0,
|
|
5210
|
+
(0, import_react27.useEffect)(() => {
|
|
4862
5211
|
if (!token || !schema) {
|
|
4863
5212
|
return;
|
|
4864
5213
|
}
|
|
@@ -4928,10 +5277,10 @@ function useCollection(collection, options = {}) {
|
|
|
4928
5277
|
scope,
|
|
4929
5278
|
reloadCount
|
|
4930
5279
|
]);
|
|
4931
|
-
const reload = (0,
|
|
5280
|
+
const reload = (0, import_react27.useCallback)(() => {
|
|
4932
5281
|
setReloadCount((count) => count + 1);
|
|
4933
5282
|
}, []);
|
|
4934
|
-
const loadMore = (0,
|
|
5283
|
+
const loadMore = (0, import_react27.useCallback)(() => {
|
|
4935
5284
|
if (!token || !cursor) {
|
|
4936
5285
|
return;
|
|
4937
5286
|
}
|
|
@@ -4955,7 +5304,7 @@ function useCollection(collection, options = {}) {
|
|
|
4955
5304
|
setLoading(false);
|
|
4956
5305
|
});
|
|
4957
5306
|
}, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
|
|
4958
|
-
const toggleSort = (0,
|
|
5307
|
+
const toggleSort = (0, import_react27.useCallback)((field) => {
|
|
4959
5308
|
setSort((current) => {
|
|
4960
5309
|
if (current?.field !== field) {
|
|
4961
5310
|
return { field, direction: "asc" };
|
|
@@ -4963,7 +5312,7 @@ function useCollection(collection, options = {}) {
|
|
|
4963
5312
|
return current.direction === "asc" ? { field, direction: "desc" } : null;
|
|
4964
5313
|
});
|
|
4965
5314
|
}, []);
|
|
4966
|
-
const create = (0,
|
|
5315
|
+
const create = (0, import_react27.useCallback)(
|
|
4967
5316
|
async (fields) => {
|
|
4968
5317
|
if (!token) {
|
|
4969
5318
|
return null;
|
|
@@ -4983,7 +5332,7 @@ function useCollection(collection, options = {}) {
|
|
|
4983
5332
|
},
|
|
4984
5333
|
[client, token, collection, scope, reload]
|
|
4985
5334
|
);
|
|
4986
|
-
const update = (0,
|
|
5335
|
+
const update = (0, import_react27.useCallback)(
|
|
4987
5336
|
async (id, fields) => {
|
|
4988
5337
|
if (!token) {
|
|
4989
5338
|
return null;
|
|
@@ -5005,7 +5354,7 @@ function useCollection(collection, options = {}) {
|
|
|
5005
5354
|
},
|
|
5006
5355
|
[client, token, collection, scope]
|
|
5007
5356
|
);
|
|
5008
|
-
const remove = (0,
|
|
5357
|
+
const remove = (0, import_react27.useCallback)(
|
|
5009
5358
|
async (id) => {
|
|
5010
5359
|
if (!token) {
|
|
5011
5360
|
return false;
|
|
@@ -5050,7 +5399,7 @@ function useCollection(collection, options = {}) {
|
|
|
5050
5399
|
}
|
|
5051
5400
|
|
|
5052
5401
|
// src/RecordForm.tsx
|
|
5053
|
-
var
|
|
5402
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5054
5403
|
function RecordForm({
|
|
5055
5404
|
collection,
|
|
5056
5405
|
recordId,
|
|
@@ -5071,22 +5420,22 @@ function RecordForm({
|
|
|
5071
5420
|
recordId
|
|
5072
5421
|
}
|
|
5073
5422
|
);
|
|
5074
|
-
const [values, setValues] = (0,
|
|
5075
|
-
const [loaded, setLoaded] = (0,
|
|
5423
|
+
const [values, setValues] = (0, import_react28.useState)(defaults ?? {});
|
|
5424
|
+
const [loaded, setLoaded] = (0, import_react28.useState)(!recordId);
|
|
5076
5425
|
const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
|
|
5077
|
-
(0,
|
|
5426
|
+
(0, import_react28.useEffect)(() => {
|
|
5078
5427
|
if (existing && !loaded) {
|
|
5079
5428
|
setValues(existing.fields);
|
|
5080
5429
|
setLoaded(true);
|
|
5081
5430
|
}
|
|
5082
5431
|
}, [existing, loaded]);
|
|
5083
5432
|
if (error) {
|
|
5084
|
-
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 }) });
|
|
5085
5434
|
}
|
|
5086
5435
|
if (!schema || !loaded) {
|
|
5087
|
-
return /* @__PURE__ */ (0,
|
|
5436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5088
5437
|
}
|
|
5089
|
-
const editable = schema.fields.filter((field) => !(0,
|
|
5438
|
+
const editable = schema.fields.filter((field) => !(0, import_sdk8.specFor)(field).computed);
|
|
5090
5439
|
async function submit(event) {
|
|
5091
5440
|
event.preventDefault();
|
|
5092
5441
|
const saved = recordId ? await update(recordId, values) : await create(values);
|
|
@@ -5094,11 +5443,11 @@ function RecordForm({
|
|
|
5094
5443
|
onSaved?.(saved.id);
|
|
5095
5444
|
}
|
|
5096
5445
|
}
|
|
5097
|
-
return /* @__PURE__ */ (0,
|
|
5098
|
-
/* @__PURE__ */ (0,
|
|
5099
|
-
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,
|
|
5100
5449
|
editable.map(
|
|
5101
|
-
(field) => field.type === "RELATION" ? /* @__PURE__ */ (0,
|
|
5450
|
+
(field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5102
5451
|
RelationPicker,
|
|
5103
5452
|
{
|
|
5104
5453
|
field,
|
|
@@ -5109,7 +5458,7 @@ function RecordForm({
|
|
|
5109
5458
|
onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
|
|
5110
5459
|
},
|
|
5111
5460
|
field.key
|
|
5112
|
-
) : /* @__PURE__ */ (0,
|
|
5461
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
5113
5462
|
FieldInput,
|
|
5114
5463
|
{
|
|
5115
5464
|
field,
|
|
@@ -5121,15 +5470,15 @@ function RecordForm({
|
|
|
5121
5470
|
field.key
|
|
5122
5471
|
)
|
|
5123
5472
|
),
|
|
5124
|
-
/* @__PURE__ */ (0,
|
|
5125
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
5126
|
-
/* @__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" })
|
|
5127
5476
|
] })
|
|
5128
5477
|
] });
|
|
5129
5478
|
}
|
|
5130
5479
|
|
|
5131
5480
|
// src/DataTable.tsx
|
|
5132
|
-
var
|
|
5481
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5133
5482
|
function DataTable({
|
|
5134
5483
|
collection,
|
|
5135
5484
|
columns,
|
|
@@ -5158,25 +5507,25 @@ function DataTable({
|
|
|
5158
5507
|
loadMore,
|
|
5159
5508
|
remove
|
|
5160
5509
|
} = useCollection(collection, options);
|
|
5161
|
-
const [editing, setEditing] = (0,
|
|
5162
|
-
const [removeFailed, setRemoveFailed] = (0,
|
|
5510
|
+
const [editing, setEditing] = (0, import_react29.useState)(null);
|
|
5511
|
+
const [removeFailed, setRemoveFailed] = (0, import_react29.useState)(null);
|
|
5163
5512
|
if (error) {
|
|
5164
|
-
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 }) });
|
|
5165
5514
|
}
|
|
5166
5515
|
if (!schema) {
|
|
5167
|
-
return /* @__PURE__ */ (0,
|
|
5516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5168
5517
|
}
|
|
5169
5518
|
const shown = columns ? (
|
|
5170
5519
|
// Ordered by what was asked for, not by the schema: a caller naming
|
|
5171
5520
|
// columns means that order.
|
|
5172
5521
|
columns.map((key) => schema.fields.find((field) => field.key === key)).filter((field) => Boolean(field))
|
|
5173
5522
|
) : schema.fields;
|
|
5174
|
-
const searchable = schema.fields.some((field) => (0,
|
|
5523
|
+
const searchable = schema.fields.some((field) => (0, import_sdk9.specFor)(field).capabilities.searchable);
|
|
5175
5524
|
const writable = canWrite && !readOnly;
|
|
5176
|
-
return /* @__PURE__ */ (0,
|
|
5177
|
-
removeFailed ? /* @__PURE__ */ (0,
|
|
5178
|
-
/* @__PURE__ */ (0,
|
|
5179
|
-
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)(
|
|
5180
5529
|
"input",
|
|
5181
5530
|
{
|
|
5182
5531
|
type: "search",
|
|
@@ -5186,25 +5535,25 @@ function DataTable({
|
|
|
5186
5535
|
value: search,
|
|
5187
5536
|
onChange: (event) => setSearch(event.target.value)
|
|
5188
5537
|
}
|
|
5189
|
-
) : /* @__PURE__ */ (0,
|
|
5190
|
-
/* @__PURE__ */ (0,
|
|
5191
|
-
/* @__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: [
|
|
5192
5541
|
total,
|
|
5193
5542
|
" ",
|
|
5194
5543
|
total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
|
|
5195
5544
|
] }),
|
|
5196
|
-
writable ? /* @__PURE__ */ (0,
|
|
5545
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
|
|
5197
5546
|
"New ",
|
|
5198
5547
|
schema.name.toLowerCase()
|
|
5199
5548
|
] }) : null
|
|
5200
5549
|
] })
|
|
5201
5550
|
] }),
|
|
5202
|
-
/* @__PURE__ */ (0,
|
|
5203
|
-
/* @__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: [
|
|
5204
5553
|
shown.map((field) => {
|
|
5205
|
-
const sortable = (0,
|
|
5554
|
+
const sortable = (0, import_sdk9.specFor)(field).capabilities.sortable;
|
|
5206
5555
|
const active = sort?.field === field.key;
|
|
5207
|
-
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)(
|
|
5208
5557
|
"button",
|
|
5209
5558
|
{
|
|
5210
5559
|
type: "button",
|
|
@@ -5212,20 +5561,20 @@ function DataTable({
|
|
|
5212
5561
|
onClick: () => toggleSort(field.key),
|
|
5213
5562
|
children: [
|
|
5214
5563
|
field.label,
|
|
5215
|
-
/* @__PURE__ */ (0,
|
|
5564
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
|
|
5216
5565
|
]
|
|
5217
5566
|
}
|
|
5218
5567
|
) : field.label }, field.key);
|
|
5219
5568
|
}),
|
|
5220
|
-
writable ? /* @__PURE__ */ (0,
|
|
5569
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
|
|
5221
5570
|
] }) }),
|
|
5222
|
-
/* @__PURE__ */ (0,
|
|
5571
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5223
5572
|
"tr",
|
|
5224
5573
|
{
|
|
5225
5574
|
className: onSelect ? "b316-row-clickable" : void 0,
|
|
5226
5575
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5227
5576
|
children: [
|
|
5228
|
-
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)(
|
|
5229
5578
|
FieldCell,
|
|
5230
5579
|
{
|
|
5231
5580
|
value: record.fields[field.key] ?? null,
|
|
@@ -5233,8 +5582,8 @@ function DataTable({
|
|
|
5233
5582
|
related: record.related[field.key]
|
|
5234
5583
|
}
|
|
5235
5584
|
) }, field.key)),
|
|
5236
|
-
writable ? /* @__PURE__ */ (0,
|
|
5237
|
-
/* @__PURE__ */ (0,
|
|
5585
|
+
writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("td", { className: "b316-table-rowactions", children: [
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5238
5587
|
"button",
|
|
5239
5588
|
{
|
|
5240
5589
|
type: "button",
|
|
@@ -5246,7 +5595,7 @@ function DataTable({
|
|
|
5246
5595
|
children: "Edit"
|
|
5247
5596
|
}
|
|
5248
5597
|
),
|
|
5249
|
-
/* @__PURE__ */ (0,
|
|
5598
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
5250
5599
|
ConfirmButton,
|
|
5251
5600
|
{
|
|
5252
5601
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5270,10 +5619,10 @@ function DataTable({
|
|
|
5270
5619
|
record.id
|
|
5271
5620
|
)) })
|
|
5272
5621
|
] }) }),
|
|
5273
|
-
records.length === 0 && !loading ? /* @__PURE__ */ (0,
|
|
5274
|
-
loading ? /* @__PURE__ */ (0,
|
|
5275
|
-
hasMore ? /* @__PURE__ */ (0,
|
|
5276
|
-
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)(
|
|
5277
5626
|
RecordForm,
|
|
5278
5627
|
{
|
|
5279
5628
|
collection,
|
|
@@ -5296,9 +5645,9 @@ function ariaSort(active, direction) {
|
|
|
5296
5645
|
}
|
|
5297
5646
|
|
|
5298
5647
|
// src/Kanban.tsx
|
|
5299
|
-
var
|
|
5300
|
-
var
|
|
5301
|
-
var
|
|
5648
|
+
var import_sdk10 = require("@base316/sdk");
|
|
5649
|
+
var import_react30 = require("react");
|
|
5650
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
5302
5651
|
function Kanban({
|
|
5303
5652
|
collection,
|
|
5304
5653
|
groupBy,
|
|
@@ -5315,17 +5664,17 @@ function Kanban({
|
|
|
5315
5664
|
limit: options.limit ?? 100,
|
|
5316
5665
|
...options
|
|
5317
5666
|
});
|
|
5318
|
-
const [dragging, setDragging] = (0,
|
|
5319
|
-
const [over, setOver] = (0,
|
|
5667
|
+
const [dragging, setDragging] = (0, import_react30.useState)(null);
|
|
5668
|
+
const [over, setOver] = (0, import_react30.useState)(null);
|
|
5320
5669
|
if (error) {
|
|
5321
|
-
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 }) });
|
|
5322
5671
|
}
|
|
5323
5672
|
if (!schema) {
|
|
5324
|
-
return /* @__PURE__ */ (0,
|
|
5673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5325
5674
|
}
|
|
5326
|
-
const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0,
|
|
5327
|
-
if (!field || !(0,
|
|
5328
|
-
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.` });
|
|
5329
5678
|
}
|
|
5330
5679
|
const columns = columnsFor(field);
|
|
5331
5680
|
const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
|
|
@@ -5333,7 +5682,7 @@ function Kanban({
|
|
|
5333
5682
|
// The grouping field is already the column heading and the title is
|
|
5334
5683
|
// already the card heading, so both would be printed twice on every card.
|
|
5335
5684
|
schema.fields.filter(
|
|
5336
|
-
(candidate) => candidate.key !== field.key && candidate.key !== (0,
|
|
5685
|
+
(candidate) => candidate.key !== field.key && candidate.key !== (0, import_sdk10.titleFieldOf)(schema.fields)?.key
|
|
5337
5686
|
).slice(0, 3)
|
|
5338
5687
|
);
|
|
5339
5688
|
async function move(record, value) {
|
|
@@ -5342,12 +5691,12 @@ function Kanban({
|
|
|
5342
5691
|
}
|
|
5343
5692
|
await update(record.id, { [field.key]: value });
|
|
5344
5693
|
}
|
|
5345
|
-
return /* @__PURE__ */ (0,
|
|
5346
|
-
/* @__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) => {
|
|
5347
5696
|
const inColumn = records.filter(
|
|
5348
5697
|
(record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
|
|
5349
5698
|
);
|
|
5350
|
-
return /* @__PURE__ */ (0,
|
|
5699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
5351
5700
|
"section",
|
|
5352
5701
|
{
|
|
5353
5702
|
className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
|
|
@@ -5371,12 +5720,12 @@ function Kanban({
|
|
|
5371
5720
|
setDragging(null);
|
|
5372
5721
|
},
|
|
5373
5722
|
children: [
|
|
5374
|
-
/* @__PURE__ */ (0,
|
|
5375
|
-
/* @__PURE__ */ (0,
|
|
5376
|
-
/* @__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 })
|
|
5377
5726
|
] }),
|
|
5378
|
-
/* @__PURE__ */ (0,
|
|
5379
|
-
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)(
|
|
5380
5729
|
"article",
|
|
5381
5730
|
{
|
|
5382
5731
|
className: "b316-board-card",
|
|
@@ -5388,10 +5737,10 @@ function Kanban({
|
|
|
5388
5737
|
},
|
|
5389
5738
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5390
5739
|
children: [
|
|
5391
|
-
/* @__PURE__ */ (0,
|
|
5392
|
-
shown.map((candidate) => /* @__PURE__ */ (0,
|
|
5393
|
-
/* @__PURE__ */ (0,
|
|
5394
|
-
/* @__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)(
|
|
5395
5744
|
FieldCell,
|
|
5396
5745
|
{
|
|
5397
5746
|
value: record.fields[candidate.key] ?? null,
|
|
@@ -5404,9 +5753,9 @@ function Kanban({
|
|
|
5404
5753
|
// Dragging is not reachable by keyboard and is awkward on a
|
|
5405
5754
|
// phone. This is the same action by other means, not a
|
|
5406
5755
|
// lesser fallback.
|
|
5407
|
-
/* @__PURE__ */ (0,
|
|
5408
|
-
/* @__PURE__ */ (0,
|
|
5409
|
-
/* @__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)(
|
|
5410
5759
|
"select",
|
|
5411
5760
|
{
|
|
5412
5761
|
className: "b316-input",
|
|
@@ -5418,7 +5767,7 @@ function Kanban({
|
|
|
5418
5767
|
);
|
|
5419
5768
|
void move(record, chosen?.value ?? null);
|
|
5420
5769
|
},
|
|
5421
|
-
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)))
|
|
5422
5771
|
}
|
|
5423
5772
|
)
|
|
5424
5773
|
] })
|
|
@@ -5427,14 +5776,14 @@ function Kanban({
|
|
|
5427
5776
|
},
|
|
5428
5777
|
record.id
|
|
5429
5778
|
)),
|
|
5430
|
-
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
|
|
5431
5780
|
] })
|
|
5432
5781
|
]
|
|
5433
5782
|
},
|
|
5434
5783
|
String(column.value)
|
|
5435
5784
|
);
|
|
5436
5785
|
}) }),
|
|
5437
|
-
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: [
|
|
5438
5787
|
"Showing ",
|
|
5439
5788
|
records.length,
|
|
5440
5789
|
" of ",
|
|
@@ -5455,9 +5804,9 @@ function columnsFor(field) {
|
|
|
5455
5804
|
}
|
|
5456
5805
|
|
|
5457
5806
|
// src/Chart.tsx
|
|
5458
|
-
var
|
|
5459
|
-
var
|
|
5460
|
-
var
|
|
5807
|
+
var import_sdk11 = require("@base316/sdk");
|
|
5808
|
+
var import_react31 = require("react");
|
|
5809
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5461
5810
|
function Chart({
|
|
5462
5811
|
collection,
|
|
5463
5812
|
x,
|
|
@@ -5476,43 +5825,43 @@ function Chart({
|
|
|
5476
5825
|
limit: options.limit ?? 200,
|
|
5477
5826
|
...options
|
|
5478
5827
|
});
|
|
5479
|
-
const axis = (0,
|
|
5828
|
+
const axis = (0, import_react31.useMemo)(() => {
|
|
5480
5829
|
if (!schema) {
|
|
5481
5830
|
return null;
|
|
5482
5831
|
}
|
|
5483
|
-
const timeFields = (0,
|
|
5832
|
+
const timeFields = (0, import_sdk11.fieldsFor)(schema.fields, "timeAxis");
|
|
5484
5833
|
const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
|
|
5485
|
-
return chosen && (0,
|
|
5834
|
+
return chosen && (0, import_sdk11.specFor)(chosen).capabilities.timeAxis ? chosen : null;
|
|
5486
5835
|
}, [schema, x]);
|
|
5487
|
-
const measure = (0,
|
|
5836
|
+
const measure = (0, import_react31.useMemo)(() => {
|
|
5488
5837
|
if (!schema || !y) {
|
|
5489
5838
|
return null;
|
|
5490
5839
|
}
|
|
5491
|
-
const candidates = (0,
|
|
5840
|
+
const candidates = (0, import_sdk11.fieldsAggregatableBy)(schema.fields, aggregate);
|
|
5492
5841
|
return candidates.find((field) => field.key === y) ?? null;
|
|
5493
5842
|
}, [schema, y, aggregate]);
|
|
5494
|
-
const buckets = (0,
|
|
5843
|
+
const buckets = (0, import_react31.useMemo)(
|
|
5495
5844
|
() => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
|
|
5496
5845
|
[records, axis, measure, aggregate, bucket, y]
|
|
5497
5846
|
);
|
|
5498
5847
|
if (error) {
|
|
5499
|
-
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 }) });
|
|
5500
5849
|
}
|
|
5501
5850
|
if (!schema || loading) {
|
|
5502
|
-
return /* @__PURE__ */ (0,
|
|
5851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5503
5852
|
}
|
|
5504
5853
|
if (!axis) {
|
|
5505
|
-
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.` });
|
|
5506
5855
|
}
|
|
5507
5856
|
if (y && !measure) {
|
|
5508
|
-
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}`}.` });
|
|
5509
5858
|
}
|
|
5510
5859
|
const peak = Math.max(...buckets.map((entry) => entry.value), 0);
|
|
5511
5860
|
const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
|
|
5512
|
-
return /* @__PURE__ */ (0,
|
|
5513
|
-
/* @__PURE__ */ (0,
|
|
5514
|
-
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0,
|
|
5515
|
-
/* @__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)(
|
|
5516
5865
|
"div",
|
|
5517
5866
|
{
|
|
5518
5867
|
className: "b316-chart-bar",
|
|
@@ -5520,18 +5869,18 @@ function Chart({
|
|
|
5520
5869
|
title: `${entry.label}: ${format(entry.value)}`
|
|
5521
5870
|
}
|
|
5522
5871
|
),
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5872
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-chart-label", children: entry.label })
|
|
5524
5873
|
] }, entry.key)) }),
|
|
5525
|
-
/* @__PURE__ */ (0,
|
|
5526
|
-
/* @__PURE__ */ (0,
|
|
5527
|
-
/* @__PURE__ */ (0,
|
|
5528
|
-
/* @__PURE__ */ (0,
|
|
5529
|
-
/* @__PURE__ */ (0,
|
|
5530
|
-
/* @__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" })
|
|
5531
5880
|
] }) }),
|
|
5532
|
-
/* @__PURE__ */ (0,
|
|
5533
|
-
/* @__PURE__ */ (0,
|
|
5534
|
-
/* @__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) })
|
|
5535
5884
|
] }, entry.key)) })
|
|
5536
5885
|
] })
|
|
5537
5886
|
] })
|
|
@@ -5589,9 +5938,9 @@ function combine(values, aggregate) {
|
|
|
5589
5938
|
}
|
|
5590
5939
|
|
|
5591
5940
|
// src/RecordDetail.tsx
|
|
5592
|
-
var
|
|
5593
|
-
var
|
|
5594
|
-
var
|
|
5941
|
+
var import_sdk12 = require("@base316/sdk");
|
|
5942
|
+
var import_react32 = require("react");
|
|
5943
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
5595
5944
|
function RecordDetail({
|
|
5596
5945
|
collection,
|
|
5597
5946
|
recordId,
|
|
@@ -5607,23 +5956,23 @@ function RecordDetail({
|
|
|
5607
5956
|
tenant,
|
|
5608
5957
|
recordId
|
|
5609
5958
|
});
|
|
5610
|
-
const [editing, setEditing] = (0,
|
|
5959
|
+
const [editing, setEditing] = (0, import_react32.useState)(false);
|
|
5611
5960
|
const record = records.find((candidate) => candidate.id === recordId);
|
|
5612
5961
|
if (error) {
|
|
5613
|
-
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 }) });
|
|
5614
5963
|
}
|
|
5615
5964
|
if (!schema || loading) {
|
|
5616
|
-
return /* @__PURE__ */ (0,
|
|
5965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5617
5966
|
}
|
|
5618
5967
|
if (!record) {
|
|
5619
|
-
return /* @__PURE__ */ (0,
|
|
5968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card", className), style, children: [
|
|
5620
5969
|
"That ",
|
|
5621
5970
|
schema.name.toLowerCase(),
|
|
5622
5971
|
" is not available."
|
|
5623
5972
|
] });
|
|
5624
5973
|
}
|
|
5625
5974
|
if (editing) {
|
|
5626
|
-
return /* @__PURE__ */ (0,
|
|
5975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5627
5976
|
RecordForm,
|
|
5628
5977
|
{
|
|
5629
5978
|
collection,
|
|
@@ -5637,12 +5986,12 @@ function RecordDetail({
|
|
|
5637
5986
|
);
|
|
5638
5987
|
}
|
|
5639
5988
|
const writable = canWrite && !readOnly;
|
|
5640
|
-
return /* @__PURE__ */ (0,
|
|
5641
|
-
/* @__PURE__ */ (0,
|
|
5642
|
-
/* @__PURE__ */ (0,
|
|
5643
|
-
/* @__PURE__ */ (0,
|
|
5644
|
-
writable ? /* @__PURE__ */ (0,
|
|
5645
|
-
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)(
|
|
5646
5995
|
ConfirmButton,
|
|
5647
5996
|
{
|
|
5648
5997
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5655,15 +6004,15 @@ function RecordDetail({
|
|
|
5655
6004
|
children: "Delete"
|
|
5656
6005
|
}
|
|
5657
6006
|
) : null,
|
|
5658
|
-
onClose ? /* @__PURE__ */ (0,
|
|
6007
|
+
onClose ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
|
|
5659
6008
|
] })
|
|
5660
6009
|
] }),
|
|
5661
|
-
/* @__PURE__ */ (0,
|
|
5662
|
-
/* @__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: [
|
|
5663
6012
|
field.label,
|
|
5664
|
-
(0,
|
|
6013
|
+
(0, import_sdk12.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
|
|
5665
6014
|
] }),
|
|
5666
|
-
/* @__PURE__ */ (0,
|
|
6015
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5667
6016
|
FieldCell,
|
|
5668
6017
|
{
|
|
5669
6018
|
value: record.fields[field.key] ?? null,
|
|
@@ -5677,8 +6026,8 @@ function RecordDetail({
|
|
|
5677
6026
|
}
|
|
5678
6027
|
|
|
5679
6028
|
// src/SubscriptionManager.tsx
|
|
5680
|
-
var
|
|
5681
|
-
var
|
|
6029
|
+
var import_react33 = require("react");
|
|
6030
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
5682
6031
|
function statusLabel(status2) {
|
|
5683
6032
|
const words = status2.toLowerCase().split("_");
|
|
5684
6033
|
return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
|
|
@@ -5718,16 +6067,16 @@ function SubscriptionManager({
|
|
|
5718
6067
|
style
|
|
5719
6068
|
}) {
|
|
5720
6069
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
5721
|
-
const [subscription, setSubscription] = (0,
|
|
5722
|
-
const [loading, setLoading] = (0,
|
|
5723
|
-
const [managedBy, setManagedBy] = (0,
|
|
5724
|
-
const [schedule, setSchedule] = (0,
|
|
5725
|
-
const [busy, setBusy] = (0,
|
|
5726
|
-
const [error, setError] = (0,
|
|
5727
|
-
const [step, setStep] = (0,
|
|
5728
|
-
const [reason, setReason] = (0,
|
|
5729
|
-
const [comment, setComment] = (0,
|
|
5730
|
-
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 () => {
|
|
5731
6080
|
if (!token) {
|
|
5732
6081
|
setSubscription(null);
|
|
5733
6082
|
setLoading(false);
|
|
@@ -5745,7 +6094,7 @@ function SubscriptionManager({
|
|
|
5745
6094
|
setLoading(false);
|
|
5746
6095
|
}
|
|
5747
6096
|
}, [client, token]);
|
|
5748
|
-
(0,
|
|
6097
|
+
(0, import_react33.useEffect)(() => {
|
|
5749
6098
|
void load();
|
|
5750
6099
|
}, [load]);
|
|
5751
6100
|
const act = async (change, failure) => {
|
|
@@ -5763,29 +6112,29 @@ function SubscriptionManager({
|
|
|
5763
6112
|
}
|
|
5764
6113
|
};
|
|
5765
6114
|
if (sessionLoading || loading) {
|
|
5766
|
-
return /* @__PURE__ */ (0,
|
|
6115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5767
6116
|
}
|
|
5768
6117
|
if (!token) {
|
|
5769
|
-
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." });
|
|
5770
6119
|
}
|
|
5771
6120
|
if (error) {
|
|
5772
|
-
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 }) });
|
|
5773
6122
|
}
|
|
5774
6123
|
if (!subscription) {
|
|
5775
|
-
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." });
|
|
5776
6125
|
}
|
|
5777
6126
|
const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
|
|
5778
6127
|
const next = schedule[0] ?? null;
|
|
5779
6128
|
const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
|
|
5780
|
-
return /* @__PURE__ */ (0,
|
|
5781
|
-
error ? /* @__PURE__ */ (0,
|
|
5782
|
-
/* @__PURE__ */ (0,
|
|
5783
|
-
/* @__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: [
|
|
5784
6133
|
statusLabel(subscription.status),
|
|
5785
6134
|
" \xB7 ",
|
|
5786
6135
|
subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
|
|
5787
6136
|
] }),
|
|
5788
|
-
next && !managedBy ? /* @__PURE__ */ (0,
|
|
6137
|
+
next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
|
|
5789
6138
|
"Moves to ",
|
|
5790
6139
|
next.plan.name,
|
|
5791
6140
|
" on ",
|
|
@@ -5793,7 +6142,7 @@ function SubscriptionManager({
|
|
|
5793
6142
|
". You keep ",
|
|
5794
6143
|
subscription.planVersion.plan.name,
|
|
5795
6144
|
" until then.",
|
|
5796
|
-
/* @__PURE__ */ (0,
|
|
6145
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5797
6146
|
"button",
|
|
5798
6147
|
{
|
|
5799
6148
|
type: "button",
|
|
@@ -5818,17 +6167,17 @@ function SubscriptionManager({
|
|
|
5818
6167
|
}
|
|
5819
6168
|
) })
|
|
5820
6169
|
] }) : null,
|
|
5821
|
-
managedBy ? /* @__PURE__ */ (0,
|
|
6170
|
+
managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5822
6171
|
"Provided by ",
|
|
5823
6172
|
managedBy.name ?? "the organization that manages your account",
|
|
5824
6173
|
". Ask them to change or cancel it."
|
|
5825
|
-
] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0,
|
|
5826
|
-
/* @__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: [
|
|
5827
6176
|
"This subscription will not renew. You keep access until ",
|
|
5828
6177
|
renews,
|
|
5829
6178
|
"."
|
|
5830
6179
|
] }),
|
|
5831
|
-
/* @__PURE__ */ (0,
|
|
6180
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5832
6181
|
"button",
|
|
5833
6182
|
{
|
|
5834
6183
|
type: "button",
|
|
@@ -5838,14 +6187,14 @@ function SubscriptionManager({
|
|
|
5838
6187
|
children: busy ? "Working\u2026" : "Resume subscription"
|
|
5839
6188
|
}
|
|
5840
6189
|
)
|
|
5841
|
-
] }) : step.kind === "offer" ? /* @__PURE__ */ (0,
|
|
5842
|
-
/* @__PURE__ */ (0,
|
|
5843
|
-
/* @__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(
|
|
5844
6193
|
step.cancellation.offer,
|
|
5845
6194
|
step.cancellation.currency
|
|
5846
6195
|
)}.` }),
|
|
5847
|
-
/* @__PURE__ */ (0,
|
|
5848
|
-
/* @__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)(
|
|
5849
6198
|
"button",
|
|
5850
6199
|
{
|
|
5851
6200
|
type: "button",
|
|
@@ -5858,7 +6207,7 @@ function SubscriptionManager({
|
|
|
5858
6207
|
children: busy ? "Working\u2026" : "Accept offer and stay"
|
|
5859
6208
|
}
|
|
5860
6209
|
),
|
|
5861
|
-
/* @__PURE__ */ (0,
|
|
6210
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5862
6211
|
"button",
|
|
5863
6212
|
{
|
|
5864
6213
|
type: "button",
|
|
@@ -5872,12 +6221,12 @@ function SubscriptionManager({
|
|
|
5872
6221
|
}
|
|
5873
6222
|
)
|
|
5874
6223
|
] }),
|
|
5875
|
-
/* @__PURE__ */ (0,
|
|
6224
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5876
6225
|
"If you cancel, you keep access until ",
|
|
5877
6226
|
renews,
|
|
5878
6227
|
"."
|
|
5879
6228
|
] })
|
|
5880
|
-
] }) : step.kind === "survey" ? /* @__PURE__ */ (0,
|
|
6229
|
+
] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
5881
6230
|
"form",
|
|
5882
6231
|
{
|
|
5883
6232
|
style: { marginTop: 14 },
|
|
@@ -5897,15 +6246,15 @@ function SubscriptionManager({
|
|
|
5897
6246
|
}, "Could not cancel. Try again.");
|
|
5898
6247
|
},
|
|
5899
6248
|
children: [
|
|
5900
|
-
/* @__PURE__ */ (0,
|
|
6249
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
|
|
5901
6250
|
"You keep access until ",
|
|
5902
6251
|
renews,
|
|
5903
6252
|
". It will not renew after that."
|
|
5904
6253
|
] }),
|
|
5905
|
-
/* @__PURE__ */ (0,
|
|
5906
|
-
/* @__PURE__ */ (0,
|
|
5907
|
-
REASONS.map((option) => /* @__PURE__ */ (0,
|
|
5908
|
-
/* @__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)(
|
|
5909
6258
|
"input",
|
|
5910
6259
|
{
|
|
5911
6260
|
type: "radio",
|
|
@@ -5915,12 +6264,12 @@ function SubscriptionManager({
|
|
|
5915
6264
|
onChange: () => setReason(option.value)
|
|
5916
6265
|
}
|
|
5917
6266
|
),
|
|
5918
|
-
/* @__PURE__ */ (0,
|
|
6267
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: option.label })
|
|
5919
6268
|
] }, option.value))
|
|
5920
6269
|
] }),
|
|
5921
|
-
/* @__PURE__ */ (0,
|
|
5922
|
-
/* @__PURE__ */ (0,
|
|
5923
|
-
/* @__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)(
|
|
5924
6273
|
"textarea",
|
|
5925
6274
|
{
|
|
5926
6275
|
className: "b316-input",
|
|
@@ -5931,9 +6280,9 @@ function SubscriptionManager({
|
|
|
5931
6280
|
}
|
|
5932
6281
|
)
|
|
5933
6282
|
] }),
|
|
5934
|
-
/* @__PURE__ */ (0,
|
|
5935
|
-
/* @__PURE__ */ (0,
|
|
5936
|
-
/* @__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)(
|
|
5937
6286
|
"button",
|
|
5938
6287
|
{
|
|
5939
6288
|
type: "button",
|
|
@@ -5949,7 +6298,7 @@ function SubscriptionManager({
|
|
|
5949
6298
|
] })
|
|
5950
6299
|
]
|
|
5951
6300
|
}
|
|
5952
|
-
) : /* @__PURE__ */ (0,
|
|
6301
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
5953
6302
|
"button",
|
|
5954
6303
|
{
|
|
5955
6304
|
type: "button",
|
|
@@ -5967,11 +6316,11 @@ function SubscriptionManager({
|
|
|
5967
6316
|
}
|
|
5968
6317
|
|
|
5969
6318
|
// src/BillingPortal.tsx
|
|
5970
|
-
var
|
|
6319
|
+
var import_react37 = require("react");
|
|
5971
6320
|
|
|
5972
6321
|
// src/CreditBalances.tsx
|
|
5973
|
-
var
|
|
5974
|
-
var
|
|
6322
|
+
var import_react34 = require("react");
|
|
6323
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
5975
6324
|
function units(value) {
|
|
5976
6325
|
return value === null ? "Unlimited" : Number(value).toLocaleString("en");
|
|
5977
6326
|
}
|
|
@@ -6006,10 +6355,10 @@ function Feature({
|
|
|
6006
6355
|
}) {
|
|
6007
6356
|
const { client, token } = useBase316();
|
|
6008
6357
|
const setting = feature.autoRecharge;
|
|
6009
|
-
const [busy, setBusy] = (0,
|
|
6010
|
-
const [error, setError] = (0,
|
|
6011
|
-
const [saved, setSaved] = (0,
|
|
6012
|
-
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 ?? "");
|
|
6013
6362
|
const unit = feature.unit ? ` ${feature.unit}` : "";
|
|
6014
6363
|
const warning = status(feature);
|
|
6015
6364
|
const buy = async () => {
|
|
@@ -6063,33 +6412,33 @@ function Feature({
|
|
|
6063
6412
|
setBusy(false);
|
|
6064
6413
|
}
|
|
6065
6414
|
};
|
|
6066
|
-
return /* @__PURE__ */ (0,
|
|
6067
|
-
/* @__PURE__ */ (0,
|
|
6068
|
-
/* @__PURE__ */ (0,
|
|
6069
|
-
/* @__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) }),
|
|
6070
6419
|
unit,
|
|
6071
6420
|
" left"
|
|
6072
6421
|
] }),
|
|
6073
|
-
/* @__PURE__ */ (0,
|
|
6422
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
|
|
6074
6423
|
feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
|
|
6075
6424
|
" ",
|
|
6076
6425
|
"\xB7 ",
|
|
6077
6426
|
units(feature.purchasedRemaining),
|
|
6078
6427
|
" purchased"
|
|
6079
6428
|
] }),
|
|
6080
|
-
warning && !managed ? /* @__PURE__ */ (0,
|
|
6081
|
-
error ? /* @__PURE__ */ (0,
|
|
6082
|
-
saved ? /* @__PURE__ */ (0,
|
|
6083
|
-
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0,
|
|
6084
|
-
/* @__PURE__ */ (0,
|
|
6085
|
-
/* @__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)(
|
|
6086
6435
|
"select",
|
|
6087
6436
|
{
|
|
6088
6437
|
className: "b316-input",
|
|
6089
6438
|
"aria-label": "Pack to buy",
|
|
6090
6439
|
value: pack,
|
|
6091
6440
|
onChange: (event) => setPack(event.target.value),
|
|
6092
|
-
children: feature.packs.map((option) => /* @__PURE__ */ (0,
|
|
6441
|
+
children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("option", { value: option.id, children: [
|
|
6093
6442
|
option.name,
|
|
6094
6443
|
" \u2014 ",
|
|
6095
6444
|
units(option.units),
|
|
@@ -6098,7 +6447,7 @@ function Feature({
|
|
|
6098
6447
|
] }, option.id))
|
|
6099
6448
|
}
|
|
6100
6449
|
),
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6450
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6102
6451
|
"button",
|
|
6103
6452
|
{
|
|
6104
6453
|
type: "button",
|
|
@@ -6109,19 +6458,19 @@ function Feature({
|
|
|
6109
6458
|
}
|
|
6110
6459
|
)
|
|
6111
6460
|
] }),
|
|
6112
|
-
/* @__PURE__ */ (0,
|
|
6113
|
-
/* @__PURE__ */ (0,
|
|
6114
|
-
/* @__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 }),
|
|
6115
6464
|
" ",
|
|
6116
6465
|
"Buy credits automatically when my balance runs low"
|
|
6117
6466
|
] }),
|
|
6118
|
-
/* @__PURE__ */ (0,
|
|
6119
|
-
/* @__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: [
|
|
6120
6469
|
"When fewer than this many",
|
|
6121
6470
|
unit,
|
|
6122
6471
|
" are left"
|
|
6123
6472
|
] }),
|
|
6124
|
-
/* @__PURE__ */ (0,
|
|
6473
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6125
6474
|
"input",
|
|
6126
6475
|
{
|
|
6127
6476
|
className: "b316-input",
|
|
@@ -6132,21 +6481,21 @@ function Feature({
|
|
|
6132
6481
|
}
|
|
6133
6482
|
)
|
|
6134
6483
|
] }),
|
|
6135
|
-
/* @__PURE__ */ (0,
|
|
6136
|
-
/* @__PURE__ */ (0,
|
|
6137
|
-
/* @__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)(
|
|
6138
6487
|
"select",
|
|
6139
6488
|
{
|
|
6140
6489
|
className: "b316-input",
|
|
6141
6490
|
name: "creditPackId",
|
|
6142
6491
|
defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
|
|
6143
|
-
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))
|
|
6144
6493
|
}
|
|
6145
6494
|
)
|
|
6146
6495
|
] }),
|
|
6147
|
-
/* @__PURE__ */ (0,
|
|
6148
|
-
/* @__PURE__ */ (0,
|
|
6149
|
-
/* @__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)(
|
|
6150
6499
|
"input",
|
|
6151
6500
|
{
|
|
6152
6501
|
className: "b316-input",
|
|
@@ -6156,13 +6505,13 @@ function Feature({
|
|
|
6156
6505
|
}
|
|
6157
6506
|
)
|
|
6158
6507
|
] }),
|
|
6159
|
-
/* @__PURE__ */ (0,
|
|
6160
|
-
/* @__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: [
|
|
6161
6510
|
"Spending at most (",
|
|
6162
6511
|
setting?.currency ?? feature.packs[0]?.currency ?? "USD",
|
|
6163
6512
|
") a month"
|
|
6164
6513
|
] }),
|
|
6165
|
-
/* @__PURE__ */ (0,
|
|
6514
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6166
6515
|
"input",
|
|
6167
6516
|
{
|
|
6168
6517
|
className: "b316-input",
|
|
@@ -6172,16 +6521,16 @@ function Feature({
|
|
|
6172
6521
|
}
|
|
6173
6522
|
)
|
|
6174
6523
|
] }),
|
|
6175
|
-
/* @__PURE__ */ (0,
|
|
6524
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
|
|
6176
6525
|
] })
|
|
6177
6526
|
] })
|
|
6178
6527
|
] });
|
|
6179
6528
|
}
|
|
6180
6529
|
function CreditBalances({ onChange, className, style }) {
|
|
6181
6530
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6182
|
-
const [state, setState] = (0,
|
|
6183
|
-
const [version, setVersion] = (0,
|
|
6184
|
-
(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)(() => {
|
|
6185
6534
|
if (!token) return;
|
|
6186
6535
|
let cancelled = false;
|
|
6187
6536
|
client.billing.credits(token).then((credits2) => {
|
|
@@ -6194,24 +6543,24 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6194
6543
|
cancelled = true;
|
|
6195
6544
|
};
|
|
6196
6545
|
}, [client, token, version]);
|
|
6197
|
-
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 });
|
|
6198
6547
|
if (sessionLoading || !token || state.kind === "loading") return null;
|
|
6199
6548
|
if (state.kind === "error") {
|
|
6200
6549
|
return wrap(
|
|
6201
|
-
/* @__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." }) })
|
|
6202
6551
|
);
|
|
6203
6552
|
}
|
|
6204
6553
|
const { credits } = state;
|
|
6205
6554
|
if (credits.features.length === 0) return null;
|
|
6206
6555
|
return wrap(
|
|
6207
|
-
/* @__PURE__ */ (0,
|
|
6208
|
-
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: [
|
|
6209
6558
|
"Credits for this account come from",
|
|
6210
6559
|
" ",
|
|
6211
6560
|
credits.managedBy.name ?? "the organization that manages it",
|
|
6212
6561
|
", which manages them."
|
|
6213
6562
|
] }) : null,
|
|
6214
|
-
credits.features.map((feature) => /* @__PURE__ */ (0,
|
|
6563
|
+
credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
6215
6564
|
Feature,
|
|
6216
6565
|
{
|
|
6217
6566
|
feature,
|
|
@@ -6228,19 +6577,19 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
6228
6577
|
}
|
|
6229
6578
|
|
|
6230
6579
|
// src/PaymentMethod.tsx
|
|
6231
|
-
var
|
|
6232
|
-
var
|
|
6580
|
+
var import_react35 = require("react");
|
|
6581
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6233
6582
|
function brandName(brand) {
|
|
6234
6583
|
if (!brand) return "Card";
|
|
6235
6584
|
return brand.charAt(0).toUpperCase() + brand.slice(1);
|
|
6236
6585
|
}
|
|
6237
6586
|
function PaymentMethod({ returnUrl, className, style }) {
|
|
6238
6587
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6239
|
-
const [state, setState] = (0,
|
|
6240
|
-
const [busy, setBusy] = (0,
|
|
6241
|
-
const [error, setError] = (0,
|
|
6242
|
-
const [version, setVersion] = (0,
|
|
6243
|
-
(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)(() => {
|
|
6244
6593
|
if (!token) return;
|
|
6245
6594
|
let cancelled = false;
|
|
6246
6595
|
client.billing.paymentMethods(token).then((result) => {
|
|
@@ -6256,7 +6605,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6256
6605
|
cancelled = true;
|
|
6257
6606
|
};
|
|
6258
6607
|
}, [client, token, version]);
|
|
6259
|
-
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 });
|
|
6260
6609
|
if (sessionLoading) return wrap("Loading\u2026");
|
|
6261
6610
|
if (!token) return wrap("Sign in to manage your payment method.");
|
|
6262
6611
|
switch (state.kind) {
|
|
@@ -6264,11 +6613,11 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6264
6613
|
return wrap("Loading\u2026");
|
|
6265
6614
|
case "error":
|
|
6266
6615
|
return wrap(
|
|
6267
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
|
|
6268
6617
|
);
|
|
6269
6618
|
case "managed":
|
|
6270
6619
|
return wrap(
|
|
6271
|
-
/* @__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." })
|
|
6272
6621
|
);
|
|
6273
6622
|
}
|
|
6274
6623
|
const card = state.cards.find((saved) => saved.isDefault) ?? null;
|
|
@@ -6287,31 +6636,31 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6287
6636
|
}
|
|
6288
6637
|
};
|
|
6289
6638
|
return wrap(
|
|
6290
|
-
/* @__PURE__ */ (0,
|
|
6291
|
-
/* @__PURE__ */ (0,
|
|
6292
|
-
card ? /* @__PURE__ */ (0,
|
|
6293
|
-
/* @__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: [
|
|
6294
6643
|
brandName(card.brand),
|
|
6295
6644
|
" ending ",
|
|
6296
6645
|
card.last4 ?? "????"
|
|
6297
6646
|
] }),
|
|
6298
|
-
card.expMonth && card.expYear ? /* @__PURE__ */ (0,
|
|
6647
|
+
card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
|
|
6299
6648
|
"Expires ",
|
|
6300
6649
|
String(card.expMonth).padStart(2, "0"),
|
|
6301
6650
|
"/",
|
|
6302
6651
|
card.expYear
|
|
6303
6652
|
] }) : null
|
|
6304
|
-
] }) : /* @__PURE__ */ (0,
|
|
6305
|
-
others.length > 0 ? /* @__PURE__ */ (0,
|
|
6306
|
-
/* @__PURE__ */ (0,
|
|
6307
|
-
others.map((saved) => /* @__PURE__ */ (0,
|
|
6308
|
-
/* @__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: [
|
|
6309
6658
|
brandName(saved.brand),
|
|
6310
6659
|
" ending ",
|
|
6311
6660
|
saved.last4 ?? "????"
|
|
6312
6661
|
] }),
|
|
6313
|
-
/* @__PURE__ */ (0,
|
|
6314
|
-
/* @__PURE__ */ (0,
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
|
|
6663
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6315
6664
|
"button",
|
|
6316
6665
|
{
|
|
6317
6666
|
type: "button",
|
|
@@ -6325,7 +6674,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6325
6674
|
}
|
|
6326
6675
|
),
|
|
6327
6676
|
" ",
|
|
6328
|
-
/* @__PURE__ */ (0,
|
|
6677
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6329
6678
|
"button",
|
|
6330
6679
|
{
|
|
6331
6680
|
type: "button",
|
|
@@ -6341,8 +6690,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6341
6690
|
] })
|
|
6342
6691
|
] }, saved.id))
|
|
6343
6692
|
] }) : null,
|
|
6344
|
-
error ? /* @__PURE__ */ (0,
|
|
6345
|
-
/* @__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)(
|
|
6346
6695
|
"button",
|
|
6347
6696
|
{
|
|
6348
6697
|
type: "button",
|
|
@@ -6371,8 +6720,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6371
6720
|
}
|
|
6372
6721
|
|
|
6373
6722
|
// src/PlanChangeReview.tsx
|
|
6374
|
-
var
|
|
6375
|
-
var
|
|
6723
|
+
var import_react36 = require("react");
|
|
6724
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
6376
6725
|
function money5(amount, currency) {
|
|
6377
6726
|
if (amount === null) return "\u2014";
|
|
6378
6727
|
const value = Number(amount);
|
|
@@ -6405,12 +6754,12 @@ function PlanChangeReview({
|
|
|
6405
6754
|
style
|
|
6406
6755
|
}) {
|
|
6407
6756
|
const { client, token } = useBase316();
|
|
6408
|
-
const [timing, setTiming] = (0,
|
|
6409
|
-
const [preview, setPreview] = (0,
|
|
6410
|
-
const [error, setError] = (0,
|
|
6411
|
-
const [needsCard, setNeedsCard] = (0,
|
|
6412
|
-
const [busy, setBusy] = (0,
|
|
6413
|
-
(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)(() => {
|
|
6414
6763
|
if (!token) return;
|
|
6415
6764
|
let cancelled = false;
|
|
6416
6765
|
client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
|
|
@@ -6427,7 +6776,7 @@ function PlanChangeReview({
|
|
|
6427
6776
|
cancelled = true;
|
|
6428
6777
|
};
|
|
6429
6778
|
}, [client, token, planVersionId, timing]);
|
|
6430
|
-
const confirm = (0,
|
|
6779
|
+
const confirm = (0, import_react36.useCallback)(async () => {
|
|
6431
6780
|
if (!token || !preview) return;
|
|
6432
6781
|
setBusy(true);
|
|
6433
6782
|
setError(null);
|
|
@@ -6448,7 +6797,7 @@ function PlanChangeReview({
|
|
|
6448
6797
|
setBusy(false);
|
|
6449
6798
|
}
|
|
6450
6799
|
}, [client, token, preview, planVersionId, onDone]);
|
|
6451
|
-
const addCard = (0,
|
|
6800
|
+
const addCard = (0, import_react36.useCallback)(async () => {
|
|
6452
6801
|
if (onNeedsCard) {
|
|
6453
6802
|
onNeedsCard();
|
|
6454
6803
|
return;
|
|
@@ -6462,12 +6811,12 @@ function PlanChangeReview({
|
|
|
6462
6811
|
setError("Cards cannot be added here right now.");
|
|
6463
6812
|
}
|
|
6464
6813
|
}, [client, token, onNeedsCard]);
|
|
6465
|
-
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 });
|
|
6466
6815
|
if (error && !preview) {
|
|
6467
6816
|
return card(
|
|
6468
|
-
/* @__PURE__ */ (0,
|
|
6469
|
-
/* @__PURE__ */ (0,
|
|
6470
|
-
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
|
|
6471
6820
|
] })
|
|
6472
6821
|
);
|
|
6473
6822
|
}
|
|
@@ -6480,26 +6829,26 @@ function PlanChangeReview({
|
|
|
6480
6829
|
const otherReason = preview.timings[other]?.reason ?? null;
|
|
6481
6830
|
const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
|
|
6482
6831
|
return card(
|
|
6483
|
-
/* @__PURE__ */ (0,
|
|
6484
|
-
/* @__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: [
|
|
6485
6834
|
"Change to ",
|
|
6486
6835
|
to.planName
|
|
6487
6836
|
] }),
|
|
6488
|
-
/* @__PURE__ */ (0,
|
|
6837
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
|
|
6489
6838
|
"From ",
|
|
6490
6839
|
from.planName
|
|
6491
6840
|
] }),
|
|
6492
|
-
error ? /* @__PURE__ */ (0,
|
|
6493
|
-
changes.length === 0 ? /* @__PURE__ */ (0,
|
|
6494
|
-
/* @__PURE__ */ (0,
|
|
6495
|
-
/* @__PURE__ */ (0,
|
|
6496
|
-
/* @__PURE__ */ (0,
|
|
6497
|
-
/* @__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 })
|
|
6498
6847
|
] }) }),
|
|
6499
|
-
/* @__PURE__ */ (0,
|
|
6500
|
-
/* @__PURE__ */ (0,
|
|
6501
|
-
/* @__PURE__ */ (0,
|
|
6502
|
-
/* @__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)(
|
|
6503
6852
|
"td",
|
|
6504
6853
|
{
|
|
6505
6854
|
className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
|
|
@@ -6508,40 +6857,40 @@ function PlanChangeReview({
|
|
|
6508
6857
|
)
|
|
6509
6858
|
] }, change.featureId)) })
|
|
6510
6859
|
] }),
|
|
6511
|
-
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0,
|
|
6860
|
+
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
|
|
6512
6861
|
"The change happens now. Your trial carries on until ",
|
|
6513
6862
|
day4(now.trialEndsAt),
|
|
6514
6863
|
", and nothing is charged before then."
|
|
6515
|
-
] }) : /* @__PURE__ */ (0,
|
|
6516
|
-
Number(now.credit) > 0 ? /* @__PURE__ */ (0,
|
|
6517
|
-
/* @__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: [
|
|
6518
6867
|
"Credit for the unused part of ",
|
|
6519
6868
|
from.planName
|
|
6520
6869
|
] }),
|
|
6521
|
-
/* @__PURE__ */ (0,
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-num", children: [
|
|
6522
6871
|
"\u2212",
|
|
6523
6872
|
money5(now.credit, from.currency)
|
|
6524
6873
|
] })
|
|
6525
6874
|
] }) : null,
|
|
6526
|
-
Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0,
|
|
6527
|
-
/* @__PURE__ */ (0,
|
|
6528
|
-
/* @__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) })
|
|
6529
6878
|
] }) : null,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6531
|
-
/* @__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: [
|
|
6532
6881
|
to.planName,
|
|
6533
6882
|
", ",
|
|
6534
6883
|
day4(now.newPeriod.start),
|
|
6535
6884
|
" \u2013 ",
|
|
6536
6885
|
day4(now.newPeriod.end)
|
|
6537
6886
|
] }),
|
|
6538
|
-
/* @__PURE__ */ (0,
|
|
6887
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
|
|
6539
6888
|
] }),
|
|
6540
|
-
now.net !== null ? /* @__PURE__ */ (0,
|
|
6541
|
-
/* @__PURE__ */ (0,
|
|
6542
|
-
/* @__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) })
|
|
6543
6892
|
] }) : null
|
|
6544
|
-
] }) : /* @__PURE__ */ (0,
|
|
6893
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
|
|
6545
6894
|
"You keep ",
|
|
6546
6895
|
from.planName,
|
|
6547
6896
|
" until ",
|
|
@@ -6554,7 +6903,7 @@ function PlanChangeReview({
|
|
|
6554
6903
|
preview.atPeriodEnd.nextInvoice.currency
|
|
6555
6904
|
)}.` : ""
|
|
6556
6905
|
] }),
|
|
6557
|
-
otherOpen ? /* @__PURE__ */ (0,
|
|
6906
|
+
otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
6558
6907
|
"button",
|
|
6559
6908
|
{
|
|
6560
6909
|
type: "button",
|
|
@@ -6565,12 +6914,12 @@ function PlanChangeReview({
|
|
|
6565
6914
|
},
|
|
6566
6915
|
children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
|
|
6567
6916
|
}
|
|
6568
|
-
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0,
|
|
6569
|
-
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: [
|
|
6570
6919
|
"A card is needed for a change that is charged now.",
|
|
6571
|
-
/* @__PURE__ */ (0,
|
|
6572
|
-
] }) : /* @__PURE__ */ (0,
|
|
6573
|
-
/* @__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)(
|
|
6574
6923
|
"button",
|
|
6575
6924
|
{
|
|
6576
6925
|
type: "button",
|
|
@@ -6580,7 +6929,7 @@ function PlanChangeReview({
|
|
|
6580
6929
|
children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
|
|
6581
6930
|
}
|
|
6582
6931
|
),
|
|
6583
|
-
onCancel ? /* @__PURE__ */ (0,
|
|
6932
|
+
onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
|
|
6584
6933
|
"Keep ",
|
|
6585
6934
|
from.planName
|
|
6586
6935
|
] }) : null
|
|
@@ -6590,7 +6939,7 @@ function PlanChangeReview({
|
|
|
6590
6939
|
}
|
|
6591
6940
|
|
|
6592
6941
|
// src/BillingPortal.tsx
|
|
6593
|
-
var
|
|
6942
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
6594
6943
|
function BillingPortal({
|
|
6595
6944
|
returnUrl,
|
|
6596
6945
|
featuredPlanKey,
|
|
@@ -6600,12 +6949,12 @@ function BillingPortal({
|
|
|
6600
6949
|
style
|
|
6601
6950
|
}) {
|
|
6602
6951
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6603
|
-
const [overview, setOverview] = (0,
|
|
6604
|
-
const [failed, setFailed] = (0,
|
|
6605
|
-
const [version, setVersion] = (0,
|
|
6606
|
-
const [reviewing, setReviewing] = (0,
|
|
6607
|
-
const [notice, setNotice] = (0,
|
|
6608
|
-
(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)(() => {
|
|
6609
6958
|
if (!token) return;
|
|
6610
6959
|
let cancelled = false;
|
|
6611
6960
|
client.billing.subscription(token).then((result) => {
|
|
@@ -6624,28 +6973,28 @@ function BillingPortal({
|
|
|
6624
6973
|
cancelled = true;
|
|
6625
6974
|
};
|
|
6626
6975
|
}, [client, token, version]);
|
|
6627
|
-
const refresh = (0,
|
|
6976
|
+
const refresh = (0, import_react37.useCallback)(() => {
|
|
6628
6977
|
setNotice(null);
|
|
6629
6978
|
setVersion((value) => value + 1);
|
|
6630
6979
|
}, []);
|
|
6631
|
-
const shell = (content) => /* @__PURE__ */ (0,
|
|
6632
|
-
if (sessionLoading) return shell(/* @__PURE__ */ (0,
|
|
6633
|
-
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." }));
|
|
6634
6983
|
if (failed) {
|
|
6635
6984
|
return shell(
|
|
6636
|
-
/* @__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." }) })
|
|
6637
6986
|
);
|
|
6638
6987
|
}
|
|
6639
|
-
if (!overview) return shell(/* @__PURE__ */ (0,
|
|
6988
|
+
if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6640
6989
|
const { subscription, managedBy, quantityPriced } = overview;
|
|
6641
6990
|
const canChange = Boolean(subscription) && !managedBy;
|
|
6642
6991
|
return shell(
|
|
6643
|
-
/* @__PURE__ */ (0,
|
|
6644
|
-
notice ? /* @__PURE__ */ (0,
|
|
6645
|
-
/* @__PURE__ */ (0,
|
|
6646
|
-
canChange ? /* @__PURE__ */ (0,
|
|
6647
|
-
canChange && quantityPriced ? /* @__PURE__ */ (0,
|
|
6648
|
-
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)(
|
|
6649
6998
|
PlanChangeReview,
|
|
6650
6999
|
{
|
|
6651
7000
|
planVersionId: reviewing,
|
|
@@ -6658,9 +7007,9 @@ function BillingPortal({
|
|
|
6658
7007
|
);
|
|
6659
7008
|
}
|
|
6660
7009
|
}
|
|
6661
|
-
) : /* @__PURE__ */ (0,
|
|
6662
|
-
/* @__PURE__ */ (0,
|
|
6663
|
-
/* @__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)(
|
|
6664
7013
|
PricingTable,
|
|
6665
7014
|
{
|
|
6666
7015
|
featuredPlanKey,
|
|
@@ -6672,17 +7021,17 @@ function BillingPortal({
|
|
|
6672
7021
|
`plans-${version}`
|
|
6673
7022
|
)
|
|
6674
7023
|
] }),
|
|
6675
|
-
/* @__PURE__ */ (0,
|
|
6676
|
-
managedBy ? null : /* @__PURE__ */ (0,
|
|
6677
|
-
/* @__PURE__ */ (0,
|
|
6678
|
-
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
|
|
6679
7028
|
] })
|
|
6680
7029
|
);
|
|
6681
7030
|
}
|
|
6682
7031
|
|
|
6683
7032
|
// src/ApiKeyManager.tsx
|
|
6684
|
-
var
|
|
6685
|
-
var
|
|
7033
|
+
var import_react38 = require("react");
|
|
7034
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
6686
7035
|
function duration(seconds) {
|
|
6687
7036
|
if (seconds % 3600 === 0) {
|
|
6688
7037
|
return `${seconds / 3600}h`;
|
|
@@ -6699,17 +7048,17 @@ function ApiKeyManager({
|
|
|
6699
7048
|
audience
|
|
6700
7049
|
}) {
|
|
6701
7050
|
const { client, token, loading: sessionLoading } = useBase316();
|
|
6702
|
-
const [resources, setResources] = (0,
|
|
6703
|
-
const [credentials, setCredentials] = (0,
|
|
6704
|
-
const [loading, setLoading] = (0,
|
|
6705
|
-
const [busy, setBusy] = (0,
|
|
6706
|
-
const [error, setError] = (0,
|
|
6707
|
-
const [creating, setCreating] = (0,
|
|
6708
|
-
const [name, setName] = (0,
|
|
6709
|
-
const [chosen, setChosen] = (0,
|
|
6710
|
-
const [resourceId, setResourceId] = (0,
|
|
6711
|
-
const [issued, setIssued] = (0,
|
|
6712
|
-
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 () => {
|
|
6713
7062
|
if (!token) {
|
|
6714
7063
|
setLoading(false);
|
|
6715
7064
|
return;
|
|
@@ -6730,20 +7079,20 @@ function ApiKeyManager({
|
|
|
6730
7079
|
setLoading(false);
|
|
6731
7080
|
}
|
|
6732
7081
|
}, [client, token, audience]);
|
|
6733
|
-
(0,
|
|
7082
|
+
(0, import_react38.useEffect)(() => {
|
|
6734
7083
|
void load();
|
|
6735
7084
|
}, [load]);
|
|
6736
7085
|
if (sessionLoading || loading) {
|
|
6737
|
-
return /* @__PURE__ */ (0,
|
|
7086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
6738
7087
|
}
|
|
6739
7088
|
if (!token) {
|
|
6740
|
-
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." });
|
|
6741
7090
|
}
|
|
6742
7091
|
if (error) {
|
|
6743
|
-
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 }) });
|
|
6744
7093
|
}
|
|
6745
7094
|
if (resources.length === 0) {
|
|
6746
|
-
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." });
|
|
6747
7096
|
}
|
|
6748
7097
|
const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
|
|
6749
7098
|
const reset = () => {
|
|
@@ -6752,37 +7101,37 @@ function ApiKeyManager({
|
|
|
6752
7101
|
setChosen([]);
|
|
6753
7102
|
setIssued(null);
|
|
6754
7103
|
};
|
|
6755
|
-
return /* @__PURE__ */ (0,
|
|
6756
|
-
error ? /* @__PURE__ */ (0,
|
|
6757
|
-
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)(
|
|
6758
7107
|
"select",
|
|
6759
7108
|
{
|
|
6760
7109
|
className: "b316-input",
|
|
6761
7110
|
value: resource.id,
|
|
6762
7111
|
onChange: (event) => setResourceId(event.target.value),
|
|
6763
7112
|
style: { marginBottom: 14 },
|
|
6764
|
-
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))
|
|
6765
7114
|
}
|
|
6766
|
-
) : /* @__PURE__ */ (0,
|
|
6767
|
-
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: [
|
|
6768
7117
|
resource.rateLimit.requestsPerWindow,
|
|
6769
7118
|
" requests per",
|
|
6770
7119
|
" ",
|
|
6771
7120
|
duration(resource.rateLimit.windowSeconds),
|
|
6772
7121
|
resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
|
|
6773
|
-
] }) : /* @__PURE__ */ (0,
|
|
6774
|
-
credentials.length === 0 ? /* @__PURE__ */ (0,
|
|
6775
|
-
/* @__PURE__ */ (0,
|
|
6776
|
-
/* @__PURE__ */ (0,
|
|
6777
|
-
/* @__PURE__ */ (0,
|
|
6778
|
-
/* @__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 }),
|
|
6779
7128
|
credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
|
|
6780
7129
|
credential.disabled ? " \xB7 Disabled" : null
|
|
6781
7130
|
] }),
|
|
6782
|
-
/* @__PURE__ */ (0,
|
|
7131
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
|
|
6783
7132
|
] }),
|
|
6784
|
-
/* @__PURE__ */ (0,
|
|
6785
|
-
/* @__PURE__ */ (0,
|
|
7133
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6786
7135
|
"button",
|
|
6787
7136
|
{
|
|
6788
7137
|
type: "button",
|
|
@@ -6811,7 +7160,7 @@ function ApiKeyManager({
|
|
|
6811
7160
|
children: "Rotate"
|
|
6812
7161
|
}
|
|
6813
7162
|
),
|
|
6814
|
-
/* @__PURE__ */ (0,
|
|
7163
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6815
7164
|
ConfirmButton,
|
|
6816
7165
|
{
|
|
6817
7166
|
className: "b316-button b316-button-secondary",
|
|
@@ -6835,11 +7184,11 @@ function ApiKeyManager({
|
|
|
6835
7184
|
)
|
|
6836
7185
|
] })
|
|
6837
7186
|
] }, credential.clientId)) }),
|
|
6838
|
-
issued ? /* @__PURE__ */ (0,
|
|
6839
|
-
/* @__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." }),
|
|
6840
7189
|
" It is shown once and cannot be retrieved again.",
|
|
6841
|
-
/* @__PURE__ */ (0,
|
|
6842
|
-
/* @__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)(
|
|
6843
7192
|
"button",
|
|
6844
7193
|
{
|
|
6845
7194
|
type: "button",
|
|
@@ -6852,7 +7201,7 @@ function ApiKeyManager({
|
|
|
6852
7201
|
children: "Copy"
|
|
6853
7202
|
}
|
|
6854
7203
|
),
|
|
6855
|
-
/* @__PURE__ */ (0,
|
|
7204
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6856
7205
|
"button",
|
|
6857
7206
|
{
|
|
6858
7207
|
type: "button",
|
|
@@ -6863,8 +7212,8 @@ function ApiKeyManager({
|
|
|
6863
7212
|
}
|
|
6864
7213
|
)
|
|
6865
7214
|
] }) : null,
|
|
6866
|
-
creating && !issued ? /* @__PURE__ */ (0,
|
|
6867
|
-
/* @__PURE__ */ (0,
|
|
7215
|
+
creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 14 }, children: [
|
|
7216
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6868
7217
|
"input",
|
|
6869
7218
|
{
|
|
6870
7219
|
className: "b316-input",
|
|
@@ -6873,9 +7222,9 @@ function ApiKeyManager({
|
|
|
6873
7222
|
onChange: (event) => setName(event.target.value)
|
|
6874
7223
|
}
|
|
6875
7224
|
),
|
|
6876
|
-
/* @__PURE__ */ (0,
|
|
6877
|
-
resource.availableScopes.map((scope) => /* @__PURE__ */ (0,
|
|
6878
|
-
/* @__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)(
|
|
6879
7228
|
"input",
|
|
6880
7229
|
{
|
|
6881
7230
|
type: "checkbox",
|
|
@@ -6885,19 +7234,19 @@ function ApiKeyManager({
|
|
|
6885
7234
|
)
|
|
6886
7235
|
}
|
|
6887
7236
|
),
|
|
6888
|
-
/* @__PURE__ */ (0,
|
|
6889
|
-
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: [
|
|
6890
7239
|
" \u2014 ",
|
|
6891
7240
|
scope.description
|
|
6892
7241
|
] }) : null
|
|
6893
7242
|
] }, scope.key)),
|
|
6894
|
-
resource.lockedScopes.map((scope) => /* @__PURE__ */ (0,
|
|
6895
|
-
/* @__PURE__ */ (0,
|
|
6896
|
-
/* @__PURE__ */ (0,
|
|
6897
|
-
/* @__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" })
|
|
6898
7247
|
] }, scope.key))
|
|
6899
7248
|
] }),
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
7249
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6901
7250
|
"button",
|
|
6902
7251
|
{
|
|
6903
7252
|
type: "button",
|
|
@@ -6931,7 +7280,7 @@ function ApiKeyManager({
|
|
|
6931
7280
|
children: "Create key"
|
|
6932
7281
|
}
|
|
6933
7282
|
),
|
|
6934
|
-
/* @__PURE__ */ (0,
|
|
7283
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6935
7284
|
"button",
|
|
6936
7285
|
{
|
|
6937
7286
|
type: "button",
|
|
@@ -6942,7 +7291,7 @@ function ApiKeyManager({
|
|
|
6942
7291
|
}
|
|
6943
7292
|
)
|
|
6944
7293
|
] }) : null,
|
|
6945
|
-
!creating && !issued ? /* @__PURE__ */ (0,
|
|
7294
|
+
!creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6946
7295
|
"button",
|
|
6947
7296
|
{
|
|
6948
7297
|
type: "button",
|
|
@@ -7017,26 +7366,45 @@ var MANIFEST = [
|
|
|
7017
7366
|
{
|
|
7018
7367
|
name: "SignIn",
|
|
7019
7368
|
kind: "component",
|
|
7020
|
-
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`).",
|
|
7021
7370
|
useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
|
|
7022
7371
|
requires: [],
|
|
7023
7372
|
props: [
|
|
7024
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
|
+
},
|
|
7025
7379
|
{
|
|
7026
7380
|
name: "passkeys",
|
|
7027
|
-
summary: "
|
|
7381
|
+
summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
|
|
7028
7382
|
required: false
|
|
7029
7383
|
},
|
|
7384
|
+
{ name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
|
|
7030
7385
|
{
|
|
7031
7386
|
name: "magicLinkRedirectUrl",
|
|
7032
|
-
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.",
|
|
7033
7400
|
required: false
|
|
7034
7401
|
},
|
|
7035
7402
|
{
|
|
7036
|
-
name: "
|
|
7037
|
-
summary: "
|
|
7403
|
+
name: "socialState",
|
|
7404
|
+
summary: "A short value carried through a social or SSO sign-in, returned by `readOAuthState`.",
|
|
7038
7405
|
required: false
|
|
7039
7406
|
},
|
|
7407
|
+
{ name: "labels", summary: "Wording for the form, for translation.", required: false },
|
|
7040
7408
|
{
|
|
7041
7409
|
name: "secondFactorLabels",
|
|
7042
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.",
|
|
@@ -7046,6 +7414,38 @@ var MANIFEST = [
|
|
|
7046
7414
|
],
|
|
7047
7415
|
seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
|
|
7048
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
|
+
},
|
|
7049
7449
|
{
|
|
7050
7450
|
name: "SignUp",
|
|
7051
7451
|
kind: "component",
|
|
@@ -7074,6 +7474,21 @@ var MANIFEST = [
|
|
|
7074
7474
|
summary: "Wording for the second-factor step, for translation.",
|
|
7075
7475
|
required: false
|
|
7076
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
|
+
},
|
|
7077
7492
|
...appearance
|
|
7078
7493
|
],
|
|
7079
7494
|
seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
|
|
@@ -7846,6 +8261,7 @@ function componentsRequiring(requirement) {
|
|
|
7846
8261
|
SecondFactorStep,
|
|
7847
8262
|
SignIn,
|
|
7848
8263
|
SignUp,
|
|
8264
|
+
SocialSignIn,
|
|
7849
8265
|
SubscriptionManager,
|
|
7850
8266
|
TeamMembers,
|
|
7851
8267
|
TwoFactorManager,
|