@base316/react 0.5.1 → 0.6.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 +42 -0
- package/dist/index.cjs +869 -648
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +696 -485
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +2 -2
- package/dist/src/QrCode.d.ts +15 -0
- package/dist/src/QrCode.d.ts.map +1 -0
- package/dist/src/SignIn.d.ts.map +1 -1
- package/dist/src/SubscriptionManager.d.ts +3 -0
- package/dist/src/SubscriptionManager.d.ts.map +1 -1
- package/dist/src/TwoFactorManager.d.ts.map +1 -1
- package/dist/src/provider.d.ts +9 -1
- package/dist/src/provider.d.ts.map +1 -1
- package/dist/src/test/harness.d.ts +2 -1
- package/dist/src/test/harness.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -642,12 +642,13 @@ function Base316Provider({
|
|
|
642
642
|
onTokenChange,
|
|
643
643
|
appearance: appearance2,
|
|
644
644
|
tenant,
|
|
645
|
+
organizationId,
|
|
645
646
|
className,
|
|
646
647
|
children
|
|
647
648
|
}) {
|
|
648
649
|
const client = useMemo(
|
|
649
|
-
() => new Base316Browser({ publishableKey, baseUrl }),
|
|
650
|
-
[publishableKey, baseUrl]
|
|
650
|
+
() => new Base316Browser({ publishableKey, baseUrl, organizationId: organizationId ?? void 0 }),
|
|
651
|
+
[publishableKey, baseUrl, organizationId]
|
|
651
652
|
);
|
|
652
653
|
useEffect(() => {
|
|
653
654
|
if (document.getElementById(STYLE_ELEMENT_ID)) {
|
|
@@ -2037,7 +2038,9 @@ function SignIn({
|
|
|
2037
2038
|
if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
|
|
2038
2039
|
return;
|
|
2039
2040
|
}
|
|
2040
|
-
if (
|
|
2041
|
+
if (cause instanceof Base316Error2 && cause.reason === "EMAIL_NOT_VERIFIED") {
|
|
2042
|
+
setError(cause.message);
|
|
2043
|
+
} else if (!conditional) {
|
|
2041
2044
|
console.error("[base316] passkey sign-in failed", cause);
|
|
2042
2045
|
setError("That passkey did not work.");
|
|
2043
2046
|
}
|
|
@@ -3041,7 +3044,61 @@ function PrivacyControls({
|
|
|
3041
3044
|
|
|
3042
3045
|
// src/TwoFactorManager.tsx
|
|
3043
3046
|
import { useState as useState14 } from "react";
|
|
3047
|
+
|
|
3048
|
+
// src/QrCode.tsx
|
|
3049
|
+
import qrcode from "qrcode-generator";
|
|
3050
|
+
import { useMemo as useMemo2 } from "react";
|
|
3044
3051
|
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3052
|
+
var QUIET_ZONE = 4;
|
|
3053
|
+
function utf8Binary(value) {
|
|
3054
|
+
let binary = "";
|
|
3055
|
+
for (const byte of new TextEncoder().encode(value)) {
|
|
3056
|
+
binary += String.fromCharCode(byte);
|
|
3057
|
+
}
|
|
3058
|
+
return binary;
|
|
3059
|
+
}
|
|
3060
|
+
function qrPath(value) {
|
|
3061
|
+
const code = qrcode(0, "M");
|
|
3062
|
+
code.addData(utf8Binary(value), "Byte");
|
|
3063
|
+
code.make();
|
|
3064
|
+
const modules = code.getModuleCount();
|
|
3065
|
+
let path = "";
|
|
3066
|
+
for (let row = 0; row < modules; row += 1) {
|
|
3067
|
+
for (let col = 0; col < modules; col += 1) {
|
|
3068
|
+
if (code.isDark(row, col)) {
|
|
3069
|
+
path += `M${col + QUIET_ZONE} ${row + QUIET_ZONE}h1v1h-1z`;
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
return { path, modules };
|
|
3074
|
+
}
|
|
3075
|
+
function QrCode({ value, label, size = 180, className }) {
|
|
3076
|
+
const { path, modules } = useMemo2(() => qrPath(value), [value]);
|
|
3077
|
+
const extent = modules + QUIET_ZONE * 2;
|
|
3078
|
+
return /* @__PURE__ */ jsxs15(
|
|
3079
|
+
"svg",
|
|
3080
|
+
{
|
|
3081
|
+
className,
|
|
3082
|
+
role: "img",
|
|
3083
|
+
"aria-label": label,
|
|
3084
|
+
width: size,
|
|
3085
|
+
height: size,
|
|
3086
|
+
viewBox: `0 0 ${extent} ${extent}`,
|
|
3087
|
+
shapeRendering: "crispEdges",
|
|
3088
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3089
|
+
children: [
|
|
3090
|
+
/* @__PURE__ */ jsx16("rect", { width: extent, height: extent, fill: "#ffffff" }),
|
|
3091
|
+
/* @__PURE__ */ jsx16("path", { d: path, fill: "#000000" })
|
|
3092
|
+
]
|
|
3093
|
+
}
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
// src/TwoFactorManager.tsx
|
|
3098
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3099
|
+
function groupKey(secret) {
|
|
3100
|
+
return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
|
|
3101
|
+
}
|
|
3045
3102
|
function TwoFactorManager({
|
|
3046
3103
|
enabled = false,
|
|
3047
3104
|
allowSms = false,
|
|
@@ -3134,17 +3191,17 @@ function TwoFactorManager({
|
|
|
3134
3191
|
setBusy(false);
|
|
3135
3192
|
}
|
|
3136
3193
|
}
|
|
3137
|
-
return /* @__PURE__ */
|
|
3138
|
-
/* @__PURE__ */
|
|
3139
|
-
error ? /* @__PURE__ */
|
|
3140
|
-
stage.name === "saved" ? /* @__PURE__ */
|
|
3141
|
-
/* @__PURE__ */
|
|
3142
|
-
/* @__PURE__ */
|
|
3143
|
-
/* @__PURE__ */
|
|
3144
|
-
] }) : stage.name === "smsNumber" ? /* @__PURE__ */
|
|
3145
|
-
/* @__PURE__ */
|
|
3146
|
-
/* @__PURE__ */
|
|
3147
|
-
/* @__PURE__ */
|
|
3194
|
+
return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-mfa", className), style, children: [
|
|
3195
|
+
/* @__PURE__ */ jsx17("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
|
|
3196
|
+
error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3197
|
+
stage.name === "saved" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-codes", children: [
|
|
3198
|
+
/* @__PURE__ */ jsx17("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." }),
|
|
3199
|
+
/* @__PURE__ */ jsx17("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsx17("code", { children: recovery }) }, recovery)) }),
|
|
3200
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
|
|
3201
|
+
] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
|
|
3202
|
+
/* @__PURE__ */ jsx17("p", { children: "We will text a code to this number now, and each time you sign in." }),
|
|
3203
|
+
/* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
|
|
3204
|
+
/* @__PURE__ */ jsx17(
|
|
3148
3205
|
"input",
|
|
3149
3206
|
{
|
|
3150
3207
|
id: "b316-mfa-phone",
|
|
@@ -3156,8 +3213,8 @@ function TwoFactorManager({
|
|
|
3156
3213
|
onChange: (event) => setPhone(event.target.value)
|
|
3157
3214
|
}
|
|
3158
3215
|
),
|
|
3159
|
-
/* @__PURE__ */
|
|
3160
|
-
/* @__PURE__ */
|
|
3216
|
+
/* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
|
|
3217
|
+
/* @__PURE__ */ jsx17(
|
|
3161
3218
|
"button",
|
|
3162
3219
|
{
|
|
3163
3220
|
type: "button",
|
|
@@ -3166,16 +3223,16 @@ function TwoFactorManager({
|
|
|
3166
3223
|
children: "Cancel"
|
|
3167
3224
|
}
|
|
3168
3225
|
),
|
|
3169
|
-
/* @__PURE__ */
|
|
3226
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
|
|
3170
3227
|
] })
|
|
3171
|
-
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */
|
|
3172
|
-
/* @__PURE__ */
|
|
3228
|
+
] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
|
|
3229
|
+
/* @__PURE__ */ jsxs16("p", { children: [
|
|
3173
3230
|
"We sent a code to ",
|
|
3174
3231
|
stage.destinationHint,
|
|
3175
3232
|
". Enter it below to turn this on."
|
|
3176
3233
|
] }),
|
|
3177
|
-
/* @__PURE__ */
|
|
3178
|
-
/* @__PURE__ */
|
|
3234
|
+
/* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3235
|
+
/* @__PURE__ */ jsx17(
|
|
3179
3236
|
"input",
|
|
3180
3237
|
{
|
|
3181
3238
|
id: "b316-mfa-code",
|
|
@@ -3186,8 +3243,8 @@ function TwoFactorManager({
|
|
|
3186
3243
|
onChange: (event) => setCode(event.target.value)
|
|
3187
3244
|
}
|
|
3188
3245
|
),
|
|
3189
|
-
/* @__PURE__ */
|
|
3190
|
-
/* @__PURE__ */
|
|
3246
|
+
/* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
|
|
3247
|
+
/* @__PURE__ */ jsx17(
|
|
3191
3248
|
"button",
|
|
3192
3249
|
{
|
|
3193
3250
|
type: "button",
|
|
@@ -3196,7 +3253,7 @@ function TwoFactorManager({
|
|
|
3196
3253
|
children: "Cancel"
|
|
3197
3254
|
}
|
|
3198
3255
|
),
|
|
3199
|
-
/* @__PURE__ */
|
|
3256
|
+
/* @__PURE__ */ jsx17(
|
|
3200
3257
|
"button",
|
|
3201
3258
|
{
|
|
3202
3259
|
type: "button",
|
|
@@ -3207,12 +3264,23 @@ function TwoFactorManager({
|
|
|
3207
3264
|
}
|
|
3208
3265
|
)
|
|
3209
3266
|
] })
|
|
3210
|
-
] }) : stage.name === "enrolling" ? /* @__PURE__ */
|
|
3211
|
-
/* @__PURE__ */
|
|
3212
|
-
/* @__PURE__ */
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3267
|
+
] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
|
|
3268
|
+
/* @__PURE__ */ jsx17("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
|
|
3269
|
+
/* @__PURE__ */ jsx17(
|
|
3270
|
+
QrCode,
|
|
3271
|
+
{
|
|
3272
|
+
className: "b316-mfa-qr",
|
|
3273
|
+
value: stage.uri,
|
|
3274
|
+
label: "QR code for your authenticator app"
|
|
3275
|
+
}
|
|
3276
|
+
),
|
|
3277
|
+
/* @__PURE__ */ jsxs16("div", { className: "b316-mfa-secret", children: [
|
|
3278
|
+
/* @__PURE__ */ jsx17("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
|
|
3279
|
+
/* @__PURE__ */ jsx17("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
|
|
3280
|
+
] }),
|
|
3281
|
+
/* @__PURE__ */ jsx17("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
|
|
3282
|
+
/* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
|
|
3283
|
+
/* @__PURE__ */ jsx17(
|
|
3216
3284
|
"input",
|
|
3217
3285
|
{
|
|
3218
3286
|
id: "b316-mfa-code",
|
|
@@ -3223,8 +3291,8 @@ function TwoFactorManager({
|
|
|
3223
3291
|
onChange: (event) => setCode(event.target.value)
|
|
3224
3292
|
}
|
|
3225
3293
|
),
|
|
3226
|
-
/* @__PURE__ */
|
|
3227
|
-
/* @__PURE__ */
|
|
3294
|
+
/* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
|
|
3295
|
+
/* @__PURE__ */ jsx17(
|
|
3228
3296
|
"button",
|
|
3229
3297
|
{
|
|
3230
3298
|
type: "button",
|
|
@@ -3233,7 +3301,7 @@ function TwoFactorManager({
|
|
|
3233
3301
|
children: "Cancel"
|
|
3234
3302
|
}
|
|
3235
3303
|
),
|
|
3236
|
-
/* @__PURE__ */
|
|
3304
|
+
/* @__PURE__ */ jsx17(
|
|
3237
3305
|
"button",
|
|
3238
3306
|
{
|
|
3239
3307
|
type: "button",
|
|
@@ -3244,9 +3312,9 @@ function TwoFactorManager({
|
|
|
3244
3312
|
}
|
|
3245
3313
|
)
|
|
3246
3314
|
] })
|
|
3247
|
-
] }) : on ? /* @__PURE__ */
|
|
3248
|
-
/* @__PURE__ */
|
|
3249
|
-
/* @__PURE__ */
|
|
3315
|
+
] }) : on ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-on", children: [
|
|
3316
|
+
/* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
|
|
3317
|
+
/* @__PURE__ */ jsx17(
|
|
3250
3318
|
ConfirmButton,
|
|
3251
3319
|
{
|
|
3252
3320
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3256,11 +3324,11 @@ function TwoFactorManager({
|
|
|
3256
3324
|
children: "Turn off"
|
|
3257
3325
|
}
|
|
3258
3326
|
)
|
|
3259
|
-
] }) : /* @__PURE__ */
|
|
3260
|
-
/* @__PURE__ */
|
|
3261
|
-
/* @__PURE__ */
|
|
3262
|
-
/* @__PURE__ */
|
|
3263
|
-
/* @__PURE__ */
|
|
3327
|
+
] }) : /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-off", children: [
|
|
3328
|
+
/* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
|
|
3329
|
+
/* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
|
|
3330
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
|
|
3331
|
+
/* @__PURE__ */ jsx17(
|
|
3264
3332
|
"button",
|
|
3265
3333
|
{
|
|
3266
3334
|
type: "button",
|
|
@@ -3270,7 +3338,7 @@ function TwoFactorManager({
|
|
|
3270
3338
|
children: "Email me a code"
|
|
3271
3339
|
}
|
|
3272
3340
|
),
|
|
3273
|
-
allowSms ? /* @__PURE__ */
|
|
3341
|
+
allowSms ? /* @__PURE__ */ jsx17(
|
|
3274
3342
|
"button",
|
|
3275
3343
|
{
|
|
3276
3344
|
type: "button",
|
|
@@ -3287,7 +3355,7 @@ function TwoFactorManager({
|
|
|
3287
3355
|
|
|
3288
3356
|
// src/ForgotPassword.tsx
|
|
3289
3357
|
import { useState as useState15 } from "react";
|
|
3290
|
-
import { jsx as
|
|
3358
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3291
3359
|
function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
3292
3360
|
const { client } = useBase316();
|
|
3293
3361
|
const [email, setEmail] = useState15("");
|
|
@@ -3309,22 +3377,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3309
3377
|
}
|
|
3310
3378
|
}
|
|
3311
3379
|
if (sent) {
|
|
3312
|
-
return /* @__PURE__ */
|
|
3313
|
-
/* @__PURE__ */
|
|
3314
|
-
/* @__PURE__ */
|
|
3380
|
+
return /* @__PURE__ */ jsxs17("div", { className: cls("b316-card", className), style, children: [
|
|
3381
|
+
/* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Check your email" }),
|
|
3382
|
+
/* @__PURE__ */ jsxs17("p", { className: "b316-muted", children: [
|
|
3315
3383
|
"If there is an account for ",
|
|
3316
3384
|
email.trim(),
|
|
3317
3385
|
", a link to set a new password is on its way."
|
|
3318
3386
|
] }),
|
|
3319
|
-
signInUrl ? /* @__PURE__ */
|
|
3387
|
+
signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3320
3388
|
] });
|
|
3321
3389
|
}
|
|
3322
|
-
return /* @__PURE__ */
|
|
3323
|
-
/* @__PURE__ */
|
|
3324
|
-
error ? /* @__PURE__ */
|
|
3325
|
-
/* @__PURE__ */
|
|
3326
|
-
/* @__PURE__ */
|
|
3327
|
-
/* @__PURE__ */
|
|
3390
|
+
return /* @__PURE__ */ jsxs17("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3391
|
+
/* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Reset your password" }),
|
|
3392
|
+
error ? /* @__PURE__ */ jsx18("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3393
|
+
/* @__PURE__ */ jsxs17("div", { className: "b316-field", children: [
|
|
3394
|
+
/* @__PURE__ */ jsx18("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
|
|
3395
|
+
/* @__PURE__ */ jsx18(
|
|
3328
3396
|
"input",
|
|
3329
3397
|
{
|
|
3330
3398
|
id: "b316-forgot-email",
|
|
@@ -3337,14 +3405,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
|
|
|
3337
3405
|
}
|
|
3338
3406
|
)
|
|
3339
3407
|
] }),
|
|
3340
|
-
/* @__PURE__ */
|
|
3341
|
-
signInUrl ? /* @__PURE__ */
|
|
3408
|
+
/* @__PURE__ */ jsx18("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
|
|
3409
|
+
signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
|
|
3342
3410
|
] });
|
|
3343
3411
|
}
|
|
3344
3412
|
|
|
3345
3413
|
// src/ResetPassword.tsx
|
|
3346
3414
|
import { useEffect as useEffect12, useState as useState16 } from "react";
|
|
3347
|
-
import { jsx as
|
|
3415
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3348
3416
|
function ResetPassword({
|
|
3349
3417
|
token: supplied,
|
|
3350
3418
|
onReset,
|
|
@@ -3394,24 +3462,24 @@ function ResetPassword({
|
|
|
3394
3462
|
}
|
|
3395
3463
|
}
|
|
3396
3464
|
if (done) {
|
|
3397
|
-
return /* @__PURE__ */
|
|
3398
|
-
/* @__PURE__ */
|
|
3399
|
-
/* @__PURE__ */
|
|
3400
|
-
signInUrl ? /* @__PURE__ */
|
|
3465
|
+
return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
|
|
3466
|
+
/* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Password changed" }),
|
|
3467
|
+
/* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "You can sign in with your new password." }),
|
|
3468
|
+
signInUrl ? /* @__PURE__ */ jsx19("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
|
|
3401
3469
|
] });
|
|
3402
3470
|
}
|
|
3403
3471
|
if (!token) {
|
|
3404
|
-
return /* @__PURE__ */
|
|
3405
|
-
/* @__PURE__ */
|
|
3406
|
-
/* @__PURE__ */
|
|
3472
|
+
return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
|
|
3473
|
+
/* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Nothing to reset" }),
|
|
3474
|
+
/* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
|
|
3407
3475
|
] });
|
|
3408
3476
|
}
|
|
3409
|
-
return /* @__PURE__ */
|
|
3410
|
-
/* @__PURE__ */
|
|
3411
|
-
error ? /* @__PURE__ */
|
|
3412
|
-
/* @__PURE__ */
|
|
3413
|
-
/* @__PURE__ */
|
|
3414
|
-
/* @__PURE__ */
|
|
3477
|
+
return /* @__PURE__ */ jsxs18("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
3478
|
+
/* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Choose a new password" }),
|
|
3479
|
+
error ? /* @__PURE__ */ jsx19("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3480
|
+
/* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
|
|
3481
|
+
/* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
|
|
3482
|
+
/* @__PURE__ */ jsx19(
|
|
3415
3483
|
"input",
|
|
3416
3484
|
{
|
|
3417
3485
|
id: "b316-reset-password",
|
|
@@ -3424,9 +3492,9 @@ function ResetPassword({
|
|
|
3424
3492
|
}
|
|
3425
3493
|
)
|
|
3426
3494
|
] }),
|
|
3427
|
-
/* @__PURE__ */
|
|
3428
|
-
/* @__PURE__ */
|
|
3429
|
-
/* @__PURE__ */
|
|
3495
|
+
/* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
|
|
3496
|
+
/* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
|
|
3497
|
+
/* @__PURE__ */ jsx19(
|
|
3430
3498
|
"input",
|
|
3431
3499
|
{
|
|
3432
3500
|
id: "b316-reset-confirm",
|
|
@@ -3439,13 +3507,13 @@ function ResetPassword({
|
|
|
3439
3507
|
}
|
|
3440
3508
|
)
|
|
3441
3509
|
] }),
|
|
3442
|
-
/* @__PURE__ */
|
|
3510
|
+
/* @__PURE__ */ jsx19("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
|
|
3443
3511
|
] });
|
|
3444
3512
|
}
|
|
3445
3513
|
|
|
3446
3514
|
// src/VerifyEmail.tsx
|
|
3447
3515
|
import { useEffect as useEffect13, useRef as useRef4, useState as useState17 } from "react";
|
|
3448
|
-
import { Fragment as Fragment5, jsx as
|
|
3516
|
+
import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3449
3517
|
function VerifyEmail({
|
|
3450
3518
|
token: supplied,
|
|
3451
3519
|
onVerified,
|
|
@@ -3482,22 +3550,22 @@ function VerifyEmail({
|
|
|
3482
3550
|
setState("failed");
|
|
3483
3551
|
});
|
|
3484
3552
|
}, [client, supplied, onVerified]);
|
|
3485
|
-
return /* @__PURE__ */
|
|
3486
|
-
/* @__PURE__ */
|
|
3487
|
-
/* @__PURE__ */
|
|
3488
|
-
continueUrl ? /* @__PURE__ */
|
|
3489
|
-
] }) : state === "failed" ? /* @__PURE__ */
|
|
3490
|
-
/* @__PURE__ */
|
|
3491
|
-
/* @__PURE__ */
|
|
3492
|
-
] }) : state === "missing" ? /* @__PURE__ */
|
|
3493
|
-
/* @__PURE__ */
|
|
3494
|
-
/* @__PURE__ */
|
|
3495
|
-
] }) : /* @__PURE__ */
|
|
3553
|
+
return /* @__PURE__ */ jsx20("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
3554
|
+
/* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Email confirmed" }),
|
|
3555
|
+
/* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
|
|
3556
|
+
continueUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
|
|
3557
|
+
] }) : state === "failed" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
3558
|
+
/* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "That link did not work" }),
|
|
3559
|
+
/* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
|
|
3560
|
+
] }) : state === "missing" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
3561
|
+
/* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
|
|
3562
|
+
/* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "This page needs the link from your email." })
|
|
3563
|
+
] }) : /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
|
|
3496
3564
|
}
|
|
3497
3565
|
|
|
3498
3566
|
// src/TeamMembers.tsx
|
|
3499
3567
|
import { useCallback as useCallback7, useEffect as useEffect14, useState as useState18 } from "react";
|
|
3500
|
-
import { Fragment as Fragment6, jsx as
|
|
3568
|
+
import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3501
3569
|
function TeamMembers({
|
|
3502
3570
|
organizationId,
|
|
3503
3571
|
onInvited,
|
|
@@ -3556,10 +3624,10 @@ function TeamMembers({
|
|
|
3556
3624
|
return null;
|
|
3557
3625
|
}
|
|
3558
3626
|
if (!teams) {
|
|
3559
|
-
return /* @__PURE__ */
|
|
3627
|
+
return /* @__PURE__ */ jsx21("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
|
|
3560
3628
|
}
|
|
3561
3629
|
if (!chosen) {
|
|
3562
|
-
return /* @__PURE__ */
|
|
3630
|
+
return /* @__PURE__ */ jsx21("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." });
|
|
3563
3631
|
}
|
|
3564
3632
|
const canManage = invitations !== null;
|
|
3565
3633
|
async function invite(event) {
|
|
@@ -3609,30 +3677,30 @@ function TeamMembers({
|
|
|
3609
3677
|
setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
|
|
3610
3678
|
}
|
|
3611
3679
|
}
|
|
3612
|
-
return /* @__PURE__ */
|
|
3613
|
-
/* @__PURE__ */
|
|
3680
|
+
return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card b316-team", className), style, children: [
|
|
3681
|
+
/* @__PURE__ */ jsx21("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
|
|
3614
3682
|
team?.inherited ? (
|
|
3615
3683
|
// Not a member of this team, so not in the list below and with nothing
|
|
3616
3684
|
// to leave: access comes from the team that manages it, and ends there.
|
|
3617
|
-
/* @__PURE__ */
|
|
3685
|
+
/* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
|
|
3618
3686
|
"You have access through",
|
|
3619
3687
|
" ",
|
|
3620
3688
|
teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
|
|
3621
3689
|
"."
|
|
3622
3690
|
] })
|
|
3623
3691
|
) : null,
|
|
3624
|
-
error ? /* @__PURE__ */
|
|
3625
|
-
/* @__PURE__ */
|
|
3626
|
-
/* @__PURE__ */
|
|
3627
|
-
/* @__PURE__ */
|
|
3628
|
-
/* @__PURE__ */
|
|
3692
|
+
error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3693
|
+
/* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
|
|
3694
|
+
/* @__PURE__ */ jsxs20("div", { children: [
|
|
3695
|
+
/* @__PURE__ */ jsx21("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
|
|
3696
|
+
/* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
|
|
3629
3697
|
member.user.email,
|
|
3630
3698
|
member.user.id === session?.userId ? " \xB7 you" : ""
|
|
3631
3699
|
] })
|
|
3632
3700
|
] }),
|
|
3633
|
-
/* @__PURE__ */
|
|
3634
|
-
/* @__PURE__ */
|
|
3635
|
-
canManage || member.user.id === session?.userId ? /* @__PURE__ */
|
|
3701
|
+
/* @__PURE__ */ jsxs20("div", { className: "b316-team-member-side", children: [
|
|
3702
|
+
/* @__PURE__ */ jsx21("span", { className: "b316-chip", children: member.role.name }),
|
|
3703
|
+
canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx21(
|
|
3636
3704
|
ConfirmButton,
|
|
3637
3705
|
{
|
|
3638
3706
|
className: "b316-button-quiet b316-danger",
|
|
@@ -3644,19 +3712,19 @@ function TeamMembers({
|
|
|
3644
3712
|
) : null
|
|
3645
3713
|
] })
|
|
3646
3714
|
] }, member.id)) }),
|
|
3647
|
-
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */
|
|
3648
|
-
/* @__PURE__ */
|
|
3649
|
-
/* @__PURE__ */
|
|
3650
|
-
/* @__PURE__ */
|
|
3651
|
-
/* @__PURE__ */
|
|
3652
|
-
/* @__PURE__ */
|
|
3715
|
+
canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs20(Fragment6, { children: [
|
|
3716
|
+
/* @__PURE__ */ jsx21("h4", { className: "b316-team-subtitle", children: "Invited" }),
|
|
3717
|
+
/* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
|
|
3718
|
+
/* @__PURE__ */ jsxs20("div", { children: [
|
|
3719
|
+
/* @__PURE__ */ jsx21("div", { children: invitation.email }),
|
|
3720
|
+
/* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
|
|
3653
3721
|
invitation.role.name,
|
|
3654
3722
|
" \xB7 expires",
|
|
3655
3723
|
" ",
|
|
3656
3724
|
new Date(invitation.expiresAt).toLocaleDateString()
|
|
3657
3725
|
] })
|
|
3658
3726
|
] }),
|
|
3659
|
-
/* @__PURE__ */
|
|
3727
|
+
/* @__PURE__ */ jsx21(
|
|
3660
3728
|
"button",
|
|
3661
3729
|
{
|
|
3662
3730
|
type: "button",
|
|
@@ -3667,10 +3735,10 @@ function TeamMembers({
|
|
|
3667
3735
|
)
|
|
3668
3736
|
] }, invitation.id)) })
|
|
3669
3737
|
] }) : null,
|
|
3670
|
-
canManage ? /* @__PURE__ */
|
|
3671
|
-
/* @__PURE__ */
|
|
3672
|
-
/* @__PURE__ */
|
|
3673
|
-
/* @__PURE__ */
|
|
3738
|
+
canManage ? /* @__PURE__ */ jsxs20("form", { className: "b316-team-invite", onSubmit: invite, children: [
|
|
3739
|
+
/* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
|
|
3740
|
+
/* @__PURE__ */ jsxs20("div", { className: "b316-team-invite-row", children: [
|
|
3741
|
+
/* @__PURE__ */ jsx21(
|
|
3674
3742
|
"input",
|
|
3675
3743
|
{
|
|
3676
3744
|
id: "b316-invite-email",
|
|
@@ -3682,19 +3750,19 @@ function TeamMembers({
|
|
|
3682
3750
|
onChange: (event) => setEmail(event.target.value)
|
|
3683
3751
|
}
|
|
3684
3752
|
),
|
|
3685
|
-
/* @__PURE__ */
|
|
3753
|
+
/* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
|
|
3686
3754
|
] })
|
|
3687
3755
|
] }) : null,
|
|
3688
|
-
copied ? /* @__PURE__ */
|
|
3689
|
-
/* @__PURE__ */
|
|
3690
|
-
/* @__PURE__ */
|
|
3756
|
+
copied ? /* @__PURE__ */ jsxs20("div", { className: "b316-team-link", children: [
|
|
3757
|
+
/* @__PURE__ */ jsx21("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
|
|
3758
|
+
/* @__PURE__ */ jsx21("code", { children: copied })
|
|
3691
3759
|
] }) : null
|
|
3692
3760
|
] });
|
|
3693
3761
|
}
|
|
3694
3762
|
|
|
3695
3763
|
// src/AcceptInvitation.tsx
|
|
3696
3764
|
import { useEffect as useEffect15, useState as useState19 } from "react";
|
|
3697
|
-
import { Fragment as Fragment7, jsx as
|
|
3765
|
+
import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3698
3766
|
function signUpUrlWithInvitation(url, token) {
|
|
3699
3767
|
const [beforeHash, ...hash] = url.split("#");
|
|
3700
3768
|
const base = beforeHash ?? "";
|
|
@@ -3761,42 +3829,42 @@ function AcceptInvitation({
|
|
|
3761
3829
|
}
|
|
3762
3830
|
}
|
|
3763
3831
|
if (state === "loading") {
|
|
3764
|
-
return /* @__PURE__ */
|
|
3832
|
+
return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
3765
3833
|
}
|
|
3766
3834
|
if (state === "invalid") {
|
|
3767
|
-
return /* @__PURE__ */
|
|
3768
|
-
/* @__PURE__ */
|
|
3769
|
-
/* @__PURE__ */
|
|
3835
|
+
return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card", className), style, children: [
|
|
3836
|
+
/* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
|
|
3837
|
+
/* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
|
|
3770
3838
|
] });
|
|
3771
3839
|
}
|
|
3772
3840
|
if (state === "accepted") {
|
|
3773
|
-
return /* @__PURE__ */
|
|
3841
|
+
return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
|
|
3774
3842
|
"You have joined ",
|
|
3775
3843
|
preview?.organizationName
|
|
3776
3844
|
] }) });
|
|
3777
3845
|
}
|
|
3778
3846
|
const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
|
|
3779
|
-
return /* @__PURE__ */
|
|
3780
|
-
/* @__PURE__ */
|
|
3847
|
+
return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card b316-invitation", className), style, children: [
|
|
3848
|
+
/* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
|
|
3781
3849
|
"Join ",
|
|
3782
3850
|
preview?.organizationName
|
|
3783
3851
|
] }),
|
|
3784
|
-
/* @__PURE__ */
|
|
3852
|
+
/* @__PURE__ */ jsxs21("p", { className: "b316-muted", children: [
|
|
3785
3853
|
"Invited as ",
|
|
3786
3854
|
preview?.email,
|
|
3787
3855
|
" \xB7 ",
|
|
3788
3856
|
preview?.roleName
|
|
3789
3857
|
] }),
|
|
3790
|
-
error ? /* @__PURE__ */
|
|
3791
|
-
!session ? /* @__PURE__ */
|
|
3792
|
-
/* @__PURE__ */
|
|
3858
|
+
error ? /* @__PURE__ */ jsx22("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
3859
|
+
!session ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
3860
|
+
/* @__PURE__ */ jsxs21("p", { children: [
|
|
3793
3861
|
"Sign in as ",
|
|
3794
3862
|
preview?.email,
|
|
3795
3863
|
" to accept."
|
|
3796
3864
|
] }),
|
|
3797
|
-
/* @__PURE__ */
|
|
3798
|
-
signInUrl ? /* @__PURE__ */
|
|
3799
|
-
signUpUrl ? /* @__PURE__ */
|
|
3865
|
+
/* @__PURE__ */ jsxs21("div", { className: "b316-invitation-actions", children: [
|
|
3866
|
+
signInUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
|
|
3867
|
+
signUpUrl ? /* @__PURE__ */ jsx22(
|
|
3800
3868
|
"a",
|
|
3801
3869
|
{
|
|
3802
3870
|
className: "b316-button-link",
|
|
@@ -3809,20 +3877,20 @@ function AcceptInvitation({
|
|
|
3809
3877
|
// Said before they press anything. The server refuses this, but
|
|
3810
3878
|
// finding out after a click reads as a broken invitation rather than
|
|
3811
3879
|
// as being signed in as the wrong person.
|
|
3812
|
-
/* @__PURE__ */
|
|
3880
|
+
/* @__PURE__ */ jsxs21("p", { children: [
|
|
3813
3881
|
"You are signed in as ",
|
|
3814
3882
|
user?.user.email,
|
|
3815
3883
|
". This invitation was sent to ",
|
|
3816
3884
|
preview?.email,
|
|
3817
3885
|
" \u2014 sign in as that address to accept it."
|
|
3818
3886
|
] })
|
|
3819
|
-
) : /* @__PURE__ */
|
|
3887
|
+
) : /* @__PURE__ */ jsx22("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
|
|
3820
3888
|
] });
|
|
3821
3889
|
}
|
|
3822
3890
|
|
|
3823
3891
|
// src/PayInvoice.tsx
|
|
3824
3892
|
import { useEffect as useEffect16, useRef as useRef5, useState as useState20 } from "react";
|
|
3825
|
-
import { jsx as
|
|
3893
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3826
3894
|
var STRIPE_SRC = "https://js.stripe.com/v3/";
|
|
3827
3895
|
function loadStripeScript() {
|
|
3828
3896
|
if (typeof window === "undefined") {
|
|
@@ -3914,12 +3982,12 @@ function PayInvoice({
|
|
|
3914
3982
|
onPaid?.();
|
|
3915
3983
|
};
|
|
3916
3984
|
if (done) {
|
|
3917
|
-
return /* @__PURE__ */
|
|
3985
|
+
return /* @__PURE__ */ jsx23("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx23("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
|
|
3918
3986
|
}
|
|
3919
|
-
return /* @__PURE__ */
|
|
3920
|
-
error ? /* @__PURE__ */
|
|
3921
|
-
/* @__PURE__ */
|
|
3922
|
-
/* @__PURE__ */
|
|
3987
|
+
return /* @__PURE__ */ jsxs22("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
|
|
3988
|
+
error ? /* @__PURE__ */ jsx23("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
|
|
3989
|
+
/* @__PURE__ */ jsx23("div", { ref: mountRef, className: "b316-pay__element" }),
|
|
3990
|
+
/* @__PURE__ */ jsx23("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
|
|
3923
3991
|
] });
|
|
3924
3992
|
}
|
|
3925
3993
|
|
|
@@ -4105,7 +4173,7 @@ function usePlans(options = {}) {
|
|
|
4105
4173
|
}
|
|
4106
4174
|
|
|
4107
4175
|
// src/PricingTable.tsx
|
|
4108
|
-
import { jsx as
|
|
4176
|
+
import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4109
4177
|
function formatAmount(amount, currency) {
|
|
4110
4178
|
if (amount === null) return "Free";
|
|
4111
4179
|
const value = Number(amount);
|
|
@@ -4171,50 +4239,50 @@ function PricingTable({
|
|
|
4171
4239
|
}
|
|
4172
4240
|
}
|
|
4173
4241
|
if (error) {
|
|
4174
|
-
return /* @__PURE__ */
|
|
4242
|
+
return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
|
|
4175
4243
|
}
|
|
4176
4244
|
if (!plans) {
|
|
4177
|
-
return /* @__PURE__ */
|
|
4245
|
+
return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
|
|
4178
4246
|
}
|
|
4179
4247
|
if (plans.length === 0) {
|
|
4180
|
-
return /* @__PURE__ */
|
|
4248
|
+
return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
|
|
4181
4249
|
}
|
|
4182
4250
|
const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
|
|
4183
4251
|
const anyDescription = plans.some((plan) => Boolean(plan.description));
|
|
4184
4252
|
const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
|
|
4185
|
-
return /* @__PURE__ */
|
|
4253
|
+
return /* @__PURE__ */ jsxs23("div", { className: cls("b316-plans", className), style, children: [
|
|
4186
4254
|
managedBy ? (
|
|
4187
4255
|
// A client company's plan comes from the firm that runs it. The table
|
|
4188
4256
|
// still shows what is on offer, with the current plan marked, but
|
|
4189
4257
|
// nothing here can be bought: it would grant this account nothing.
|
|
4190
|
-
/* @__PURE__ */
|
|
4258
|
+
/* @__PURE__ */ jsxs23("div", { className: "b316-plans-managed b316-muted", children: [
|
|
4191
4259
|
"Your plan is provided by ",
|
|
4192
4260
|
managedBy.name ?? "the organization that manages your account",
|
|
4193
4261
|
". Ask them to change it."
|
|
4194
4262
|
] })
|
|
4195
|
-
) : lastError ? /* @__PURE__ */
|
|
4263
|
+
) : lastError ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
|
|
4196
4264
|
plans.map((plan) => {
|
|
4197
4265
|
const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
|
|
4198
4266
|
const isCurrent = current === plan.planVersionId;
|
|
4199
4267
|
const featured = featuredPlanKey === plan.key;
|
|
4200
|
-
return /* @__PURE__ */
|
|
4268
|
+
return /* @__PURE__ */ jsxs23(
|
|
4201
4269
|
"div",
|
|
4202
4270
|
{
|
|
4203
4271
|
className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
|
|
4204
4272
|
children: [
|
|
4205
|
-
/* @__PURE__ */
|
|
4206
|
-
anyFeatured ? /* @__PURE__ */
|
|
4207
|
-
/* @__PURE__ */
|
|
4208
|
-
anyDescription ? /* @__PURE__ */
|
|
4273
|
+
/* @__PURE__ */ jsxs23("div", { className: "b316-plan-head", children: [
|
|
4274
|
+
anyFeatured ? /* @__PURE__ */ jsx24("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
|
|
4275
|
+
/* @__PURE__ */ jsx24("div", { className: "b316-plan-name", children: plan.name }),
|
|
4276
|
+
anyDescription ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
|
|
4209
4277
|
] }),
|
|
4210
|
-
/* @__PURE__ */
|
|
4211
|
-
/* @__PURE__ */
|
|
4212
|
-
/* @__PURE__ */
|
|
4213
|
-
anyTrial ? /* @__PURE__ */
|
|
4278
|
+
/* @__PURE__ */ jsxs23("div", { className: "b316-plan-pricing", children: [
|
|
4279
|
+
/* @__PURE__ */ jsx24("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
|
|
4280
|
+
/* @__PURE__ */ jsx24("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
|
|
4281
|
+
anyTrial ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
|
|
4214
4282
|
] }),
|
|
4215
|
-
/* @__PURE__ */
|
|
4216
|
-
/* @__PURE__ */
|
|
4217
|
-
/* @__PURE__ */
|
|
4283
|
+
/* @__PURE__ */ jsx24("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs23("li", { className: "b316-plan-feature", children: [
|
|
4284
|
+
/* @__PURE__ */ jsx24("span", { children: entitlement.featureName }),
|
|
4285
|
+
/* @__PURE__ */ jsx24("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
|
|
4218
4286
|
// A usage price on the feature makes the limit an
|
|
4219
4287
|
// allowance billed past, not a ceiling — the same
|
|
4220
4288
|
// rule `check()` applies (any non-FLAT price).
|
|
@@ -4223,7 +4291,7 @@ function PricingTable({
|
|
|
4223
4291
|
) ? `${entitlement.limit} included` : entitlement.limit
|
|
4224
4292
|
) })
|
|
4225
4293
|
] }, entitlement.featureId)) }),
|
|
4226
|
-
/* @__PURE__ */
|
|
4294
|
+
/* @__PURE__ */ jsx24("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx24(
|
|
4227
4295
|
"button",
|
|
4228
4296
|
{
|
|
4229
4297
|
type: "button",
|
|
@@ -4252,7 +4320,7 @@ import {
|
|
|
4252
4320
|
formatAddress,
|
|
4253
4321
|
specFor
|
|
4254
4322
|
} from "@base316/sdk";
|
|
4255
|
-
import { jsx as
|
|
4323
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4256
4324
|
function formatNumber(value, fraction = 0) {
|
|
4257
4325
|
const number = Number(value);
|
|
4258
4326
|
return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
|
|
@@ -4274,10 +4342,10 @@ function formatDuration(value) {
|
|
|
4274
4342
|
}
|
|
4275
4343
|
function FieldCell({ value, field, related }) {
|
|
4276
4344
|
if (field.type === "RELATION") {
|
|
4277
|
-
return related?.title ?? (related?.id ? /* @__PURE__ */
|
|
4345
|
+
return related?.title ?? (related?.id ? /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: related.id }) : "\u2014");
|
|
4278
4346
|
}
|
|
4279
4347
|
if (value === null || value === void 0 || value === "") {
|
|
4280
|
-
return /* @__PURE__ */
|
|
4348
|
+
return /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2014" });
|
|
4281
4349
|
}
|
|
4282
4350
|
switch (field.type) {
|
|
4283
4351
|
case "BOOLEAN":
|
|
@@ -4290,9 +4358,9 @@ function FieldCell({ value, field, related }) {
|
|
|
4290
4358
|
return formatDuration(value);
|
|
4291
4359
|
case "RATING": {
|
|
4292
4360
|
const stars = Math.round(Number(value));
|
|
4293
|
-
return /* @__PURE__ */
|
|
4361
|
+
return /* @__PURE__ */ jsxs24("span", { "aria-label": `${stars} out of 5`, children: [
|
|
4294
4362
|
"\u2605".repeat(stars),
|
|
4295
|
-
/* @__PURE__ */
|
|
4363
|
+
/* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
|
|
4296
4364
|
] });
|
|
4297
4365
|
}
|
|
4298
4366
|
case "DATE":
|
|
@@ -4300,15 +4368,15 @@ function FieldCell({ value, field, related }) {
|
|
|
4300
4368
|
case "DATETIME":
|
|
4301
4369
|
return new Date(String(value)).toLocaleString();
|
|
4302
4370
|
case "SELECT":
|
|
4303
|
-
return /* @__PURE__ */
|
|
4371
|
+
return /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(value) });
|
|
4304
4372
|
case "MULTISELECT":
|
|
4305
|
-
return /* @__PURE__ */
|
|
4373
|
+
return /* @__PURE__ */ jsx25("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(item) }, String(item))) });
|
|
4306
4374
|
case "URL":
|
|
4307
|
-
return /* @__PURE__ */
|
|
4375
|
+
return /* @__PURE__ */ jsx25("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
|
|
4308
4376
|
case "EMAIL":
|
|
4309
|
-
return /* @__PURE__ */
|
|
4377
|
+
return /* @__PURE__ */ jsx25("a", { href: `mailto:${String(value)}`, children: String(value) });
|
|
4310
4378
|
case "PHONE":
|
|
4311
|
-
return /* @__PURE__ */
|
|
4379
|
+
return /* @__PURE__ */ jsx25("a", { href: `tel:${String(value)}`, children: String(value) });
|
|
4312
4380
|
case "ADDRESS":
|
|
4313
4381
|
return formatAddress(value);
|
|
4314
4382
|
case "ATTACHMENT": {
|
|
@@ -4320,7 +4388,7 @@ function FieldCell({ value, field, related }) {
|
|
|
4320
4388
|
return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
|
|
4321
4389
|
}
|
|
4322
4390
|
case "JSON":
|
|
4323
|
-
return /* @__PURE__ */
|
|
4391
|
+
return /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
|
|
4324
4392
|
default:
|
|
4325
4393
|
return String(value);
|
|
4326
4394
|
}
|
|
@@ -4341,7 +4409,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4341
4409
|
function control() {
|
|
4342
4410
|
switch (field.type) {
|
|
4343
4411
|
case "LONGTEXT":
|
|
4344
|
-
return /* @__PURE__ */
|
|
4412
|
+
return /* @__PURE__ */ jsx25(
|
|
4345
4413
|
"textarea",
|
|
4346
4414
|
{
|
|
4347
4415
|
...common,
|
|
@@ -4351,7 +4419,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4351
4419
|
}
|
|
4352
4420
|
);
|
|
4353
4421
|
case "BOOLEAN":
|
|
4354
|
-
return /* @__PURE__ */
|
|
4422
|
+
return /* @__PURE__ */ jsx25(
|
|
4355
4423
|
"input",
|
|
4356
4424
|
{
|
|
4357
4425
|
...common,
|
|
@@ -4362,22 +4430,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4362
4430
|
}
|
|
4363
4431
|
);
|
|
4364
4432
|
case "SELECT":
|
|
4365
|
-
return /* @__PURE__ */
|
|
4433
|
+
return /* @__PURE__ */ jsxs24(
|
|
4366
4434
|
"select",
|
|
4367
4435
|
{
|
|
4368
4436
|
...common,
|
|
4369
4437
|
value: value === null || value === void 0 ? "" : String(value),
|
|
4370
4438
|
onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
|
|
4371
4439
|
children: [
|
|
4372
|
-
field.required ? null : /* @__PURE__ */
|
|
4373
|
-
(field.options ?? []).map((option) => /* @__PURE__ */
|
|
4440
|
+
field.required ? null : /* @__PURE__ */ jsx25("option", { value: "", children: "\u2014" }),
|
|
4441
|
+
(field.options ?? []).map((option) => /* @__PURE__ */ jsx25("option", { value: option, children: option }, option))
|
|
4374
4442
|
]
|
|
4375
4443
|
}
|
|
4376
4444
|
);
|
|
4377
4445
|
case "MULTISELECT": {
|
|
4378
4446
|
const selected = new Set(Array.isArray(value) ? value.map(String) : []);
|
|
4379
|
-
return /* @__PURE__ */
|
|
4380
|
-
/* @__PURE__ */
|
|
4447
|
+
return /* @__PURE__ */ jsx25("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs24("label", { className: "b316-choice", children: [
|
|
4448
|
+
/* @__PURE__ */ jsx25(
|
|
4381
4449
|
"input",
|
|
4382
4450
|
{
|
|
4383
4451
|
type: "checkbox",
|
|
@@ -4400,7 +4468,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4400
4468
|
case "NUMBER":
|
|
4401
4469
|
case "MONEY":
|
|
4402
4470
|
case "PERCENT":
|
|
4403
|
-
return /* @__PURE__ */
|
|
4471
|
+
return /* @__PURE__ */ jsx25(
|
|
4404
4472
|
"input",
|
|
4405
4473
|
{
|
|
4406
4474
|
...common,
|
|
@@ -4411,7 +4479,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4411
4479
|
}
|
|
4412
4480
|
);
|
|
4413
4481
|
case "RATING":
|
|
4414
|
-
return /* @__PURE__ */
|
|
4482
|
+
return /* @__PURE__ */ jsx25(
|
|
4415
4483
|
"input",
|
|
4416
4484
|
{
|
|
4417
4485
|
...common,
|
|
@@ -4425,8 +4493,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4425
4493
|
);
|
|
4426
4494
|
case "DURATION": {
|
|
4427
4495
|
const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
|
|
4428
|
-
return /* @__PURE__ */
|
|
4429
|
-
/* @__PURE__ */
|
|
4496
|
+
return /* @__PURE__ */ jsxs24("div", { className: "b316-suffixed", children: [
|
|
4497
|
+
/* @__PURE__ */ jsx25(
|
|
4430
4498
|
"input",
|
|
4431
4499
|
{
|
|
4432
4500
|
...common,
|
|
@@ -4436,11 +4504,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4436
4504
|
onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
|
|
4437
4505
|
}
|
|
4438
4506
|
),
|
|
4439
|
-
/* @__PURE__ */
|
|
4507
|
+
/* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "minutes" })
|
|
4440
4508
|
] });
|
|
4441
4509
|
}
|
|
4442
4510
|
case "DATE":
|
|
4443
|
-
return /* @__PURE__ */
|
|
4511
|
+
return /* @__PURE__ */ jsx25(
|
|
4444
4512
|
"input",
|
|
4445
4513
|
{
|
|
4446
4514
|
...common,
|
|
@@ -4450,7 +4518,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4450
4518
|
}
|
|
4451
4519
|
);
|
|
4452
4520
|
case "DATETIME":
|
|
4453
|
-
return /* @__PURE__ */
|
|
4521
|
+
return /* @__PURE__ */ jsx25(
|
|
4454
4522
|
"input",
|
|
4455
4523
|
{
|
|
4456
4524
|
...common,
|
|
@@ -4463,7 +4531,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4463
4531
|
);
|
|
4464
4532
|
case "ADDRESS": {
|
|
4465
4533
|
const address = value ?? {};
|
|
4466
|
-
const part = (key, label) => /* @__PURE__ */
|
|
4534
|
+
const part = (key, label) => /* @__PURE__ */ jsx25(
|
|
4467
4535
|
"input",
|
|
4468
4536
|
{
|
|
4469
4537
|
className: "b316-input",
|
|
@@ -4475,7 +4543,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4475
4543
|
},
|
|
4476
4544
|
key
|
|
4477
4545
|
);
|
|
4478
|
-
return /* @__PURE__ */
|
|
4546
|
+
return /* @__PURE__ */ jsxs24("div", { className: "b316-address", children: [
|
|
4479
4547
|
part("line1", "Address line 1"),
|
|
4480
4548
|
part("line2", "Address line 2"),
|
|
4481
4549
|
part("city", "City"),
|
|
@@ -4485,7 +4553,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4485
4553
|
] });
|
|
4486
4554
|
}
|
|
4487
4555
|
case "EMAIL":
|
|
4488
|
-
return /* @__PURE__ */
|
|
4556
|
+
return /* @__PURE__ */ jsx25(
|
|
4489
4557
|
"input",
|
|
4490
4558
|
{
|
|
4491
4559
|
...common,
|
|
@@ -4495,7 +4563,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4495
4563
|
}
|
|
4496
4564
|
);
|
|
4497
4565
|
case "URL":
|
|
4498
|
-
return /* @__PURE__ */
|
|
4566
|
+
return /* @__PURE__ */ jsx25(
|
|
4499
4567
|
"input",
|
|
4500
4568
|
{
|
|
4501
4569
|
...common,
|
|
@@ -4505,7 +4573,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4505
4573
|
}
|
|
4506
4574
|
);
|
|
4507
4575
|
case "PHONE":
|
|
4508
|
-
return /* @__PURE__ */
|
|
4576
|
+
return /* @__PURE__ */ jsx25(
|
|
4509
4577
|
"input",
|
|
4510
4578
|
{
|
|
4511
4579
|
...common,
|
|
@@ -4515,7 +4583,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4515
4583
|
}
|
|
4516
4584
|
);
|
|
4517
4585
|
default:
|
|
4518
|
-
return /* @__PURE__ */
|
|
4586
|
+
return /* @__PURE__ */ jsx25(
|
|
4519
4587
|
"input",
|
|
4520
4588
|
{
|
|
4521
4589
|
...common,
|
|
@@ -4526,14 +4594,14 @@ function FieldInput({ value, field, onChange, error, disabled }) {
|
|
|
4526
4594
|
);
|
|
4527
4595
|
}
|
|
4528
4596
|
}
|
|
4529
|
-
return /* @__PURE__ */
|
|
4530
|
-
/* @__PURE__ */
|
|
4597
|
+
return /* @__PURE__ */ jsxs24("div", { className: "b316-field", children: [
|
|
4598
|
+
/* @__PURE__ */ jsxs24("label", { className: "b316-label", htmlFor: id, children: [
|
|
4531
4599
|
field.label,
|
|
4532
|
-
field.required ? /* @__PURE__ */
|
|
4600
|
+
field.required ? /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4533
4601
|
] }),
|
|
4534
4602
|
control(),
|
|
4535
|
-
field.description ? /* @__PURE__ */
|
|
4536
|
-
error ? /* @__PURE__ */
|
|
4603
|
+
field.description ? /* @__PURE__ */ jsx25("div", { className: "b316-hint", children: field.description }) : null,
|
|
4604
|
+
error ? /* @__PURE__ */ jsx25("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
|
|
4537
4605
|
] });
|
|
4538
4606
|
}
|
|
4539
4607
|
|
|
@@ -4543,7 +4611,7 @@ import { useEffect as useEffect21, useState as useState26 } from "react";
|
|
|
4543
4611
|
|
|
4544
4612
|
// src/RelationPicker.tsx
|
|
4545
4613
|
import { useEffect as useEffect19, useRef as useRef7, useState as useState24 } from "react";
|
|
4546
|
-
import { Fragment as Fragment8, jsx as
|
|
4614
|
+
import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
4547
4615
|
function RelationPicker({
|
|
4548
4616
|
field,
|
|
4549
4617
|
value,
|
|
@@ -4614,14 +4682,14 @@ function RelationPicker({
|
|
|
4614
4682
|
document.removeEventListener("mousedown", onDocumentClick);
|
|
4615
4683
|
};
|
|
4616
4684
|
}, [open]);
|
|
4617
|
-
return /* @__PURE__ */
|
|
4618
|
-
/* @__PURE__ */
|
|
4685
|
+
return /* @__PURE__ */ jsxs25("div", { className: "b316-field", ref: box, children: [
|
|
4686
|
+
/* @__PURE__ */ jsxs25("label", { className: "b316-label", htmlFor: id, children: [
|
|
4619
4687
|
field.label,
|
|
4620
|
-
field.required ? /* @__PURE__ */
|
|
4688
|
+
field.required ? /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4621
4689
|
] }),
|
|
4622
|
-
value && !open ? /* @__PURE__ */
|
|
4623
|
-
/* @__PURE__ */
|
|
4624
|
-
disabled ? null : /* @__PURE__ */
|
|
4690
|
+
value && !open ? /* @__PURE__ */ jsxs25("div", { className: "b316-relation-chosen", children: [
|
|
4691
|
+
/* @__PURE__ */ jsx26("span", { children: chosenTitle ?? value }),
|
|
4692
|
+
disabled ? null : /* @__PURE__ */ jsx26(
|
|
4625
4693
|
"button",
|
|
4626
4694
|
{
|
|
4627
4695
|
type: "button",
|
|
@@ -4633,7 +4701,7 @@ function RelationPicker({
|
|
|
4633
4701
|
children: "Change"
|
|
4634
4702
|
}
|
|
4635
4703
|
),
|
|
4636
|
-
disabled || field.required ? null : /* @__PURE__ */
|
|
4704
|
+
disabled || field.required ? null : /* @__PURE__ */ jsx26(
|
|
4637
4705
|
"button",
|
|
4638
4706
|
{
|
|
4639
4707
|
type: "button",
|
|
@@ -4643,8 +4711,8 @@ function RelationPicker({
|
|
|
4643
4711
|
children: "Clear"
|
|
4644
4712
|
}
|
|
4645
4713
|
)
|
|
4646
|
-
] }) : /* @__PURE__ */
|
|
4647
|
-
/* @__PURE__ */
|
|
4714
|
+
] }) : /* @__PURE__ */ jsxs25(Fragment8, { children: [
|
|
4715
|
+
/* @__PURE__ */ jsx26(
|
|
4648
4716
|
"input",
|
|
4649
4717
|
{
|
|
4650
4718
|
id,
|
|
@@ -4665,7 +4733,7 @@ function RelationPicker({
|
|
|
4665
4733
|
}
|
|
4666
4734
|
}
|
|
4667
4735
|
),
|
|
4668
|
-
open ? /* @__PURE__ */
|
|
4736
|
+
open ? /* @__PURE__ */ jsx26("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx26("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(
|
|
4669
4737
|
"button",
|
|
4670
4738
|
{
|
|
4671
4739
|
type: "button",
|
|
@@ -4681,13 +4749,13 @@ function RelationPicker({
|
|
|
4681
4749
|
}
|
|
4682
4750
|
) }, result.id)) }) : null
|
|
4683
4751
|
] }),
|
|
4684
|
-
field.description ? /* @__PURE__ */
|
|
4685
|
-
error ? /* @__PURE__ */
|
|
4752
|
+
field.description ? /* @__PURE__ */ jsx26("div", { className: "b316-hint", children: field.description }) : null,
|
|
4753
|
+
error ? /* @__PURE__ */ jsx26("div", { className: "b316-error", role: "alert", children: error }) : null
|
|
4686
4754
|
] });
|
|
4687
4755
|
}
|
|
4688
4756
|
|
|
4689
4757
|
// src/useCollection.ts
|
|
4690
|
-
import { useCallback as useCallback9, useEffect as useEffect20, useMemo as
|
|
4758
|
+
import { useCallback as useCallback9, useEffect as useEffect20, useMemo as useMemo3, useState as useState25 } from "react";
|
|
4691
4759
|
function fieldErrorFrom(cause) {
|
|
4692
4760
|
const param = cause?.param;
|
|
4693
4761
|
const message = cause instanceof Error ? cause.message : "That value was not accepted.";
|
|
@@ -4711,7 +4779,7 @@ function useCollection(collection, options = {}) {
|
|
|
4711
4779
|
const [saving, setSaving] = useState25(false);
|
|
4712
4780
|
const { tenant, limit, recordId } = options;
|
|
4713
4781
|
const fixedFilters = JSON.stringify(options.filters ?? []);
|
|
4714
|
-
const scope =
|
|
4782
|
+
const scope = useMemo3(() => tenant ? { tenant } : void 0, [tenant]);
|
|
4715
4783
|
useEffect20(() => {
|
|
4716
4784
|
if (!token) {
|
|
4717
4785
|
return;
|
|
@@ -4923,7 +4991,7 @@ function useCollection(collection, options = {}) {
|
|
|
4923
4991
|
}
|
|
4924
4992
|
|
|
4925
4993
|
// src/RecordForm.tsx
|
|
4926
|
-
import { jsx as
|
|
4994
|
+
import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
4927
4995
|
function RecordForm({
|
|
4928
4996
|
collection,
|
|
4929
4997
|
recordId,
|
|
@@ -4954,10 +5022,10 @@ function RecordForm({
|
|
|
4954
5022
|
}
|
|
4955
5023
|
}, [existing, loaded]);
|
|
4956
5024
|
if (error) {
|
|
4957
|
-
return /* @__PURE__ */
|
|
5025
|
+
return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: error }) });
|
|
4958
5026
|
}
|
|
4959
5027
|
if (!schema || !loaded) {
|
|
4960
|
-
return /* @__PURE__ */
|
|
5028
|
+
return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
4961
5029
|
}
|
|
4962
5030
|
const editable = schema.fields.filter((field) => !specFor2(field).computed);
|
|
4963
5031
|
async function submit(event) {
|
|
@@ -4967,11 +5035,11 @@ function RecordForm({
|
|
|
4967
5035
|
onSaved?.(saved.id);
|
|
4968
5036
|
}
|
|
4969
5037
|
}
|
|
4970
|
-
return /* @__PURE__ */
|
|
4971
|
-
/* @__PURE__ */
|
|
4972
|
-
fieldErrors._ ? /* @__PURE__ */
|
|
5038
|
+
return /* @__PURE__ */ jsxs26("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
|
|
5039
|
+
/* @__PURE__ */ jsx27("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
|
|
5040
|
+
fieldErrors._ ? /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
|
|
4973
5041
|
editable.map(
|
|
4974
|
-
(field) => field.type === "RELATION" ? /* @__PURE__ */
|
|
5042
|
+
(field) => field.type === "RELATION" ? /* @__PURE__ */ jsx27(
|
|
4975
5043
|
RelationPicker,
|
|
4976
5044
|
{
|
|
4977
5045
|
field,
|
|
@@ -4982,7 +5050,7 @@ function RecordForm({
|
|
|
4982
5050
|
onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
|
|
4983
5051
|
},
|
|
4984
5052
|
field.key
|
|
4985
|
-
) : /* @__PURE__ */
|
|
5053
|
+
) : /* @__PURE__ */ jsx27(
|
|
4986
5054
|
FieldInput,
|
|
4987
5055
|
{
|
|
4988
5056
|
field,
|
|
@@ -4994,15 +5062,15 @@ function RecordForm({
|
|
|
4994
5062
|
field.key
|
|
4995
5063
|
)
|
|
4996
5064
|
),
|
|
4997
|
-
/* @__PURE__ */
|
|
4998
|
-
onCancel ? /* @__PURE__ */
|
|
4999
|
-
/* @__PURE__ */
|
|
5065
|
+
/* @__PURE__ */ jsxs26("div", { className: "b316-form-actions", children: [
|
|
5066
|
+
onCancel ? /* @__PURE__ */ jsx27("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
|
|
5067
|
+
/* @__PURE__ */ jsx27("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
|
|
5000
5068
|
] })
|
|
5001
5069
|
] });
|
|
5002
5070
|
}
|
|
5003
5071
|
|
|
5004
5072
|
// src/DataTable.tsx
|
|
5005
|
-
import { jsx as
|
|
5073
|
+
import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5006
5074
|
function DataTable({
|
|
5007
5075
|
collection,
|
|
5008
5076
|
columns,
|
|
@@ -5034,10 +5102,10 @@ function DataTable({
|
|
|
5034
5102
|
const [editing, setEditing] = useState27(null);
|
|
5035
5103
|
const [removeFailed, setRemoveFailed] = useState27(null);
|
|
5036
5104
|
if (error) {
|
|
5037
|
-
return /* @__PURE__ */
|
|
5105
|
+
return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5038
5106
|
}
|
|
5039
5107
|
if (!schema) {
|
|
5040
|
-
return /* @__PURE__ */
|
|
5108
|
+
return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5041
5109
|
}
|
|
5042
5110
|
const shown = columns ? (
|
|
5043
5111
|
// Ordered by what was asked for, not by the schema: a caller naming
|
|
@@ -5046,10 +5114,10 @@ function DataTable({
|
|
|
5046
5114
|
) : schema.fields;
|
|
5047
5115
|
const searchable = schema.fields.some((field) => specFor3(field).capabilities.searchable);
|
|
5048
5116
|
const writable = canWrite && !readOnly;
|
|
5049
|
-
return /* @__PURE__ */
|
|
5050
|
-
removeFailed ? /* @__PURE__ */
|
|
5051
|
-
/* @__PURE__ */
|
|
5052
|
-
searchable && !hideSearch ? /* @__PURE__ */
|
|
5117
|
+
return /* @__PURE__ */ jsxs27("div", { className: cls("b316-table-wrap", className), style, children: [
|
|
5118
|
+
removeFailed ? /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
|
|
5119
|
+
/* @__PURE__ */ jsxs27("div", { className: "b316-table-bar", children: [
|
|
5120
|
+
searchable && !hideSearch ? /* @__PURE__ */ jsx28(
|
|
5053
5121
|
"input",
|
|
5054
5122
|
{
|
|
5055
5123
|
type: "search",
|
|
@@ -5059,25 +5127,25 @@ function DataTable({
|
|
|
5059
5127
|
value: search,
|
|
5060
5128
|
onChange: (event) => setSearch(event.target.value)
|
|
5061
5129
|
}
|
|
5062
|
-
) : /* @__PURE__ */
|
|
5063
|
-
/* @__PURE__ */
|
|
5064
|
-
/* @__PURE__ */
|
|
5130
|
+
) : /* @__PURE__ */ jsx28("span", {}),
|
|
5131
|
+
/* @__PURE__ */ jsxs27("div", { className: "b316-table-actions", children: [
|
|
5132
|
+
/* @__PURE__ */ jsxs27("span", { className: "b316-muted", children: [
|
|
5065
5133
|
total,
|
|
5066
5134
|
" ",
|
|
5067
5135
|
total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
|
|
5068
5136
|
] }),
|
|
5069
|
-
writable ? /* @__PURE__ */
|
|
5137
|
+
writable ? /* @__PURE__ */ jsxs27("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
|
|
5070
5138
|
"New ",
|
|
5071
5139
|
schema.name.toLowerCase()
|
|
5072
5140
|
] }) : null
|
|
5073
5141
|
] })
|
|
5074
5142
|
] }),
|
|
5075
|
-
/* @__PURE__ */
|
|
5076
|
-
/* @__PURE__ */
|
|
5143
|
+
/* @__PURE__ */ jsx28("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs27("table", { className: "b316-table", children: [
|
|
5144
|
+
/* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs27("tr", { children: [
|
|
5077
5145
|
shown.map((field) => {
|
|
5078
5146
|
const sortable = specFor3(field).capabilities.sortable;
|
|
5079
5147
|
const active = sort?.field === field.key;
|
|
5080
|
-
return /* @__PURE__ */
|
|
5148
|
+
return /* @__PURE__ */ jsx28("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs27(
|
|
5081
5149
|
"button",
|
|
5082
5150
|
{
|
|
5083
5151
|
type: "button",
|
|
@@ -5085,20 +5153,20 @@ function DataTable({
|
|
|
5085
5153
|
onClick: () => toggleSort(field.key),
|
|
5086
5154
|
children: [
|
|
5087
5155
|
field.label,
|
|
5088
|
-
/* @__PURE__ */
|
|
5156
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
|
|
5089
5157
|
]
|
|
5090
5158
|
}
|
|
5091
5159
|
) : field.label }, field.key);
|
|
5092
5160
|
}),
|
|
5093
|
-
writable ? /* @__PURE__ */
|
|
5161
|
+
writable ? /* @__PURE__ */ jsx28("th", { scope: "col", className: "b316-table-rowactions" }) : null
|
|
5094
5162
|
] }) }),
|
|
5095
|
-
/* @__PURE__ */
|
|
5163
|
+
/* @__PURE__ */ jsx28("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs27(
|
|
5096
5164
|
"tr",
|
|
5097
5165
|
{
|
|
5098
5166
|
className: onSelect ? "b316-row-clickable" : void 0,
|
|
5099
5167
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5100
5168
|
children: [
|
|
5101
|
-
shown.map((field) => /* @__PURE__ */
|
|
5169
|
+
shown.map((field) => /* @__PURE__ */ jsx28("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx28(
|
|
5102
5170
|
FieldCell,
|
|
5103
5171
|
{
|
|
5104
5172
|
value: record.fields[field.key] ?? null,
|
|
@@ -5106,8 +5174,8 @@ function DataTable({
|
|
|
5106
5174
|
related: record.related[field.key]
|
|
5107
5175
|
}
|
|
5108
5176
|
) }, field.key)),
|
|
5109
|
-
writable ? /* @__PURE__ */
|
|
5110
|
-
/* @__PURE__ */
|
|
5177
|
+
writable ? /* @__PURE__ */ jsxs27("td", { className: "b316-table-rowactions", children: [
|
|
5178
|
+
/* @__PURE__ */ jsx28(
|
|
5111
5179
|
"button",
|
|
5112
5180
|
{
|
|
5113
5181
|
type: "button",
|
|
@@ -5119,7 +5187,7 @@ function DataTable({
|
|
|
5119
5187
|
children: "Edit"
|
|
5120
5188
|
}
|
|
5121
5189
|
),
|
|
5122
|
-
/* @__PURE__ */
|
|
5190
|
+
/* @__PURE__ */ jsx28(
|
|
5123
5191
|
ConfirmButton,
|
|
5124
5192
|
{
|
|
5125
5193
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5143,10 +5211,10 @@ function DataTable({
|
|
|
5143
5211
|
record.id
|
|
5144
5212
|
)) })
|
|
5145
5213
|
] }) }),
|
|
5146
|
-
records.length === 0 && !loading ? /* @__PURE__ */
|
|
5147
|
-
loading ? /* @__PURE__ */
|
|
5148
|
-
hasMore ? /* @__PURE__ */
|
|
5149
|
-
editing ? /* @__PURE__ */
|
|
5214
|
+
records.length === 0 && !loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
|
|
5215
|
+
loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
|
|
5216
|
+
hasMore ? /* @__PURE__ */ jsx28("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
|
|
5217
|
+
editing ? /* @__PURE__ */ jsx28(
|
|
5150
5218
|
RecordForm,
|
|
5151
5219
|
{
|
|
5152
5220
|
collection,
|
|
@@ -5175,7 +5243,7 @@ import {
|
|
|
5175
5243
|
titleFieldOf
|
|
5176
5244
|
} from "@base316/sdk";
|
|
5177
5245
|
import { useState as useState28 } from "react";
|
|
5178
|
-
import { jsx as
|
|
5246
|
+
import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5179
5247
|
function Kanban({
|
|
5180
5248
|
collection,
|
|
5181
5249
|
groupBy,
|
|
@@ -5195,14 +5263,14 @@ function Kanban({
|
|
|
5195
5263
|
const [dragging, setDragging] = useState28(null);
|
|
5196
5264
|
const [over, setOver] = useState28(null);
|
|
5197
5265
|
if (error) {
|
|
5198
|
-
return /* @__PURE__ */
|
|
5266
|
+
return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5199
5267
|
}
|
|
5200
5268
|
if (!schema) {
|
|
5201
|
-
return /* @__PURE__ */
|
|
5269
|
+
return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5202
5270
|
}
|
|
5203
5271
|
const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : defaultGroupFieldOf(schema.fields);
|
|
5204
5272
|
if (!field || !specFor4(field).capabilities.groupable) {
|
|
5205
|
-
return /* @__PURE__ */
|
|
5273
|
+
return /* @__PURE__ */ jsx29("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.` });
|
|
5206
5274
|
}
|
|
5207
5275
|
const columns = columnsFor(field);
|
|
5208
5276
|
const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
|
|
@@ -5219,12 +5287,12 @@ function Kanban({
|
|
|
5219
5287
|
}
|
|
5220
5288
|
await update(record.id, { [field.key]: value });
|
|
5221
5289
|
}
|
|
5222
|
-
return /* @__PURE__ */
|
|
5223
|
-
/* @__PURE__ */
|
|
5290
|
+
return /* @__PURE__ */ jsxs28("div", { className: cls("b316-board-wrap", className), style, children: [
|
|
5291
|
+
/* @__PURE__ */ jsx29("div", { className: "b316-board", role: "list", children: columns.map((column) => {
|
|
5224
5292
|
const inColumn = records.filter(
|
|
5225
5293
|
(record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
|
|
5226
5294
|
);
|
|
5227
|
-
return /* @__PURE__ */
|
|
5295
|
+
return /* @__PURE__ */ jsxs28(
|
|
5228
5296
|
"section",
|
|
5229
5297
|
{
|
|
5230
5298
|
className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
|
|
@@ -5248,12 +5316,12 @@ function Kanban({
|
|
|
5248
5316
|
setDragging(null);
|
|
5249
5317
|
},
|
|
5250
5318
|
children: [
|
|
5251
|
-
/* @__PURE__ */
|
|
5252
|
-
/* @__PURE__ */
|
|
5253
|
-
/* @__PURE__ */
|
|
5319
|
+
/* @__PURE__ */ jsxs28("header", { className: "b316-board-head", children: [
|
|
5320
|
+
/* @__PURE__ */ jsx29("span", { className: "b316-board-title", children: column.label }),
|
|
5321
|
+
/* @__PURE__ */ jsx29("span", { className: "b316-muted", children: inColumn.length })
|
|
5254
5322
|
] }),
|
|
5255
|
-
/* @__PURE__ */
|
|
5256
|
-
inColumn.map((record) => /* @__PURE__ */
|
|
5323
|
+
/* @__PURE__ */ jsxs28("div", { className: "b316-board-cards", children: [
|
|
5324
|
+
inColumn.map((record) => /* @__PURE__ */ jsxs28(
|
|
5257
5325
|
"article",
|
|
5258
5326
|
{
|
|
5259
5327
|
className: "b316-board-card",
|
|
@@ -5265,10 +5333,10 @@ function Kanban({
|
|
|
5265
5333
|
},
|
|
5266
5334
|
onClick: onSelect ? () => onSelect(record) : void 0,
|
|
5267
5335
|
children: [
|
|
5268
|
-
/* @__PURE__ */
|
|
5269
|
-
shown.map((candidate) => /* @__PURE__ */
|
|
5270
|
-
/* @__PURE__ */
|
|
5271
|
-
/* @__PURE__ */
|
|
5336
|
+
/* @__PURE__ */ jsx29("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
|
|
5337
|
+
shown.map((candidate) => /* @__PURE__ */ jsxs28("div", { className: "b316-board-card-field", children: [
|
|
5338
|
+
/* @__PURE__ */ jsx29("span", { className: "b316-muted", children: candidate.label }),
|
|
5339
|
+
/* @__PURE__ */ jsx29(
|
|
5272
5340
|
FieldCell,
|
|
5273
5341
|
{
|
|
5274
5342
|
value: record.fields[candidate.key] ?? null,
|
|
@@ -5281,9 +5349,9 @@ function Kanban({
|
|
|
5281
5349
|
// Dragging is not reachable by keyboard and is awkward on a
|
|
5282
5350
|
// phone. This is the same action by other means, not a
|
|
5283
5351
|
// lesser fallback.
|
|
5284
|
-
/* @__PURE__ */
|
|
5285
|
-
/* @__PURE__ */
|
|
5286
|
-
/* @__PURE__ */
|
|
5352
|
+
/* @__PURE__ */ jsxs28("label", { className: "b316-board-move", children: [
|
|
5353
|
+
/* @__PURE__ */ jsx29("span", { className: "b316-muted", children: "Move to" }),
|
|
5354
|
+
/* @__PURE__ */ jsx29(
|
|
5287
5355
|
"select",
|
|
5288
5356
|
{
|
|
5289
5357
|
className: "b316-input",
|
|
@@ -5295,7 +5363,7 @@ function Kanban({
|
|
|
5295
5363
|
);
|
|
5296
5364
|
void move(record, chosen?.value ?? null);
|
|
5297
5365
|
},
|
|
5298
|
-
children: columns.map((candidate) => /* @__PURE__ */
|
|
5366
|
+
children: columns.map((candidate) => /* @__PURE__ */ jsx29("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
|
|
5299
5367
|
}
|
|
5300
5368
|
)
|
|
5301
5369
|
] })
|
|
@@ -5304,14 +5372,14 @@ function Kanban({
|
|
|
5304
5372
|
},
|
|
5305
5373
|
record.id
|
|
5306
5374
|
)),
|
|
5307
|
-
inColumn.length === 0 ? /* @__PURE__ */
|
|
5375
|
+
inColumn.length === 0 ? /* @__PURE__ */ jsx29("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
|
|
5308
5376
|
] })
|
|
5309
5377
|
]
|
|
5310
5378
|
},
|
|
5311
5379
|
String(column.value)
|
|
5312
5380
|
);
|
|
5313
5381
|
}) }),
|
|
5314
|
-
hasMore ? /* @__PURE__ */
|
|
5382
|
+
hasMore ? /* @__PURE__ */ jsx29("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
|
|
5315
5383
|
"Showing ",
|
|
5316
5384
|
records.length,
|
|
5317
5385
|
" of ",
|
|
@@ -5337,8 +5405,8 @@ import {
|
|
|
5337
5405
|
fieldsFor,
|
|
5338
5406
|
specFor as specFor5
|
|
5339
5407
|
} from "@base316/sdk";
|
|
5340
|
-
import { useMemo as
|
|
5341
|
-
import { jsx as
|
|
5408
|
+
import { useMemo as useMemo4 } from "react";
|
|
5409
|
+
import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5342
5410
|
function Chart({
|
|
5343
5411
|
collection,
|
|
5344
5412
|
x,
|
|
@@ -5357,7 +5425,7 @@ function Chart({
|
|
|
5357
5425
|
limit: options.limit ?? 200,
|
|
5358
5426
|
...options
|
|
5359
5427
|
});
|
|
5360
|
-
const axis =
|
|
5428
|
+
const axis = useMemo4(() => {
|
|
5361
5429
|
if (!schema) {
|
|
5362
5430
|
return null;
|
|
5363
5431
|
}
|
|
@@ -5365,35 +5433,35 @@ function Chart({
|
|
|
5365
5433
|
const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
|
|
5366
5434
|
return chosen && specFor5(chosen).capabilities.timeAxis ? chosen : null;
|
|
5367
5435
|
}, [schema, x]);
|
|
5368
|
-
const measure =
|
|
5436
|
+
const measure = useMemo4(() => {
|
|
5369
5437
|
if (!schema || !y) {
|
|
5370
5438
|
return null;
|
|
5371
5439
|
}
|
|
5372
5440
|
const candidates = fieldsAggregatableBy(schema.fields, aggregate);
|
|
5373
5441
|
return candidates.find((field) => field.key === y) ?? null;
|
|
5374
5442
|
}, [schema, y, aggregate]);
|
|
5375
|
-
const buckets =
|
|
5443
|
+
const buckets = useMemo4(
|
|
5376
5444
|
() => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
|
|
5377
5445
|
[records, axis, measure, aggregate, bucket, y]
|
|
5378
5446
|
);
|
|
5379
5447
|
if (error) {
|
|
5380
|
-
return /* @__PURE__ */
|
|
5448
|
+
return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5381
5449
|
}
|
|
5382
5450
|
if (!schema || loading) {
|
|
5383
|
-
return /* @__PURE__ */
|
|
5451
|
+
return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5384
5452
|
}
|
|
5385
5453
|
if (!axis) {
|
|
5386
|
-
return /* @__PURE__ */
|
|
5454
|
+
return /* @__PURE__ */ jsx30("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.` });
|
|
5387
5455
|
}
|
|
5388
5456
|
if (y && !measure) {
|
|
5389
|
-
return /* @__PURE__ */
|
|
5457
|
+
return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
|
|
5390
5458
|
}
|
|
5391
5459
|
const peak = Math.max(...buckets.map((entry) => entry.value), 0);
|
|
5392
5460
|
const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
|
|
5393
|
-
return /* @__PURE__ */
|
|
5394
|
-
/* @__PURE__ */
|
|
5395
|
-
buckets.length === 0 || peak === 0 ? /* @__PURE__ */
|
|
5396
|
-
/* @__PURE__ */
|
|
5461
|
+
return /* @__PURE__ */ jsxs29("figure", { className: cls("b316-card b316-chart", className), style, children: [
|
|
5462
|
+
/* @__PURE__ */ jsx30("figcaption", { className: "b316-chart-title", children: heading }),
|
|
5463
|
+
buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx30("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs29("div", { className: "b316-chart-col", children: [
|
|
5464
|
+
/* @__PURE__ */ jsx30(
|
|
5397
5465
|
"div",
|
|
5398
5466
|
{
|
|
5399
5467
|
className: "b316-chart-bar",
|
|
@@ -5401,18 +5469,18 @@ function Chart({
|
|
|
5401
5469
|
title: `${entry.label}: ${format(entry.value)}`
|
|
5402
5470
|
}
|
|
5403
5471
|
),
|
|
5404
|
-
/* @__PURE__ */
|
|
5472
|
+
/* @__PURE__ */ jsx30("span", { className: "b316-chart-label", children: entry.label })
|
|
5405
5473
|
] }, entry.key)) }),
|
|
5406
|
-
/* @__PURE__ */
|
|
5407
|
-
/* @__PURE__ */
|
|
5408
|
-
/* @__PURE__ */
|
|
5409
|
-
/* @__PURE__ */
|
|
5410
|
-
/* @__PURE__ */
|
|
5411
|
-
/* @__PURE__ */
|
|
5474
|
+
/* @__PURE__ */ jsxs29("details", { className: "b316-chart-data", children: [
|
|
5475
|
+
/* @__PURE__ */ jsx30("summary", { children: "Values" }),
|
|
5476
|
+
/* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
|
|
5477
|
+
/* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
|
|
5478
|
+
/* @__PURE__ */ jsx30("th", { scope: "col", children: axis.label }),
|
|
5479
|
+
/* @__PURE__ */ jsx30("th", { scope: "col", children: measure ? measure.label : "Count" })
|
|
5412
5480
|
] }) }),
|
|
5413
|
-
/* @__PURE__ */
|
|
5414
|
-
/* @__PURE__ */
|
|
5415
|
-
/* @__PURE__ */
|
|
5481
|
+
/* @__PURE__ */ jsx30("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs29("tr", { children: [
|
|
5482
|
+
/* @__PURE__ */ jsx30("td", { children: entry.label }),
|
|
5483
|
+
/* @__PURE__ */ jsx30("td", { children: format(entry.value) })
|
|
5416
5484
|
] }, entry.key)) })
|
|
5417
5485
|
] })
|
|
5418
5486
|
] })
|
|
@@ -5472,7 +5540,7 @@ function combine(values, aggregate) {
|
|
|
5472
5540
|
// src/RecordDetail.tsx
|
|
5473
5541
|
import { specFor as specFor6 } from "@base316/sdk";
|
|
5474
5542
|
import { useState as useState29 } from "react";
|
|
5475
|
-
import { jsx as
|
|
5543
|
+
import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5476
5544
|
function RecordDetail({
|
|
5477
5545
|
collection,
|
|
5478
5546
|
recordId,
|
|
@@ -5491,20 +5559,20 @@ function RecordDetail({
|
|
|
5491
5559
|
const [editing, setEditing] = useState29(false);
|
|
5492
5560
|
const record = records.find((candidate) => candidate.id === recordId);
|
|
5493
5561
|
if (error) {
|
|
5494
|
-
return /* @__PURE__ */
|
|
5562
|
+
return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5495
5563
|
}
|
|
5496
5564
|
if (!schema || loading) {
|
|
5497
|
-
return /* @__PURE__ */
|
|
5565
|
+
return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5498
5566
|
}
|
|
5499
5567
|
if (!record) {
|
|
5500
|
-
return /* @__PURE__ */
|
|
5568
|
+
return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card", className), style, children: [
|
|
5501
5569
|
"That ",
|
|
5502
5570
|
schema.name.toLowerCase(),
|
|
5503
5571
|
" is not available."
|
|
5504
5572
|
] });
|
|
5505
5573
|
}
|
|
5506
5574
|
if (editing) {
|
|
5507
|
-
return /* @__PURE__ */
|
|
5575
|
+
return /* @__PURE__ */ jsx31(
|
|
5508
5576
|
RecordForm,
|
|
5509
5577
|
{
|
|
5510
5578
|
collection,
|
|
@@ -5518,12 +5586,12 @@ function RecordDetail({
|
|
|
5518
5586
|
);
|
|
5519
5587
|
}
|
|
5520
5588
|
const writable = canWrite && !readOnly;
|
|
5521
|
-
return /* @__PURE__ */
|
|
5522
|
-
/* @__PURE__ */
|
|
5523
|
-
/* @__PURE__ */
|
|
5524
|
-
/* @__PURE__ */
|
|
5525
|
-
writable ? /* @__PURE__ */
|
|
5526
|
-
writable ? /* @__PURE__ */
|
|
5589
|
+
return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card b316-detail", className), style, children: [
|
|
5590
|
+
/* @__PURE__ */ jsxs30("div", { className: "b316-detail-head", children: [
|
|
5591
|
+
/* @__PURE__ */ jsx31("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
|
|
5592
|
+
/* @__PURE__ */ jsxs30("div", { className: "b316-detail-actions", children: [
|
|
5593
|
+
writable ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
|
|
5594
|
+
writable ? /* @__PURE__ */ jsx31(
|
|
5527
5595
|
ConfirmButton,
|
|
5528
5596
|
{
|
|
5529
5597
|
className: "b316-button-quiet b316-danger",
|
|
@@ -5536,15 +5604,15 @@ function RecordDetail({
|
|
|
5536
5604
|
children: "Delete"
|
|
5537
5605
|
}
|
|
5538
5606
|
) : null,
|
|
5539
|
-
onClose ? /* @__PURE__ */
|
|
5607
|
+
onClose ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
|
|
5540
5608
|
] })
|
|
5541
5609
|
] }),
|
|
5542
|
-
/* @__PURE__ */
|
|
5543
|
-
/* @__PURE__ */
|
|
5610
|
+
/* @__PURE__ */ jsx31("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs30("div", { className: "b316-detail-row", children: [
|
|
5611
|
+
/* @__PURE__ */ jsxs30("dt", { className: "b316-label", children: [
|
|
5544
5612
|
field.label,
|
|
5545
|
-
specFor6(field).computed ? /* @__PURE__ */
|
|
5613
|
+
specFor6(field).computed ? /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: " (calculated)" }) : null
|
|
5546
5614
|
] }),
|
|
5547
|
-
/* @__PURE__ */
|
|
5615
|
+
/* @__PURE__ */ jsx31("dd", { children: /* @__PURE__ */ jsx31(
|
|
5548
5616
|
FieldCell,
|
|
5549
5617
|
{
|
|
5550
5618
|
value: record.fields[field.key] ?? null,
|
|
@@ -5559,11 +5627,40 @@ function RecordDetail({
|
|
|
5559
5627
|
|
|
5560
5628
|
// src/SubscriptionManager.tsx
|
|
5561
5629
|
import { useCallback as useCallback10, useEffect as useEffect22, useState as useState30 } from "react";
|
|
5562
|
-
import { jsx as
|
|
5630
|
+
import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5563
5631
|
function statusLabel(status2) {
|
|
5564
5632
|
const words = status2.toLowerCase().split("_");
|
|
5565
5633
|
return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
|
|
5566
5634
|
}
|
|
5635
|
+
var REASONS = [
|
|
5636
|
+
{ value: "TOO_EXPENSIVE", label: "It costs too much" },
|
|
5637
|
+
{ value: "NOT_USING", label: "I am not using it enough" },
|
|
5638
|
+
{ value: "MISSING_FEATURES", label: "It is missing something I need" },
|
|
5639
|
+
{ value: "SWITCHING", label: "I am switching to something else" },
|
|
5640
|
+
{ value: "TECHNICAL_ISSUES", label: "It did not work well for me" },
|
|
5641
|
+
{ value: "TEMPORARY", label: "I only needed it for a while" },
|
|
5642
|
+
{ value: "OTHER", label: "Something else" }
|
|
5643
|
+
];
|
|
5644
|
+
function describeRetentionOffer(offer, currency) {
|
|
5645
|
+
let amount;
|
|
5646
|
+
if (offer.type === "PERCENTAGE") {
|
|
5647
|
+
amount = `${Number(offer.percentOff ?? "0")}% off`;
|
|
5648
|
+
} else {
|
|
5649
|
+
try {
|
|
5650
|
+
amount = `${new Intl.NumberFormat(void 0, {
|
|
5651
|
+
style: "currency",
|
|
5652
|
+
currency: offer.currency ?? currency
|
|
5653
|
+
}).format(Number(offer.amountOff ?? "0"))} off`;
|
|
5654
|
+
} catch {
|
|
5655
|
+
amount = `${offer.amountOff} ${offer.currency ?? currency} off`;
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
if (offer.duration === "FOREVER") {
|
|
5659
|
+
return `${amount} for as long as you stay subscribed`;
|
|
5660
|
+
}
|
|
5661
|
+
const periods = offer.duration === "ONCE" ? 1 : offer.durationInPeriods ?? 1;
|
|
5662
|
+
return periods === 1 ? `${amount} your next invoice` : `${amount} your next ${periods} invoices`;
|
|
5663
|
+
}
|
|
5567
5664
|
function SubscriptionManager({
|
|
5568
5665
|
onChange,
|
|
5569
5666
|
className,
|
|
@@ -5576,6 +5673,9 @@ function SubscriptionManager({
|
|
|
5576
5673
|
const [schedule, setSchedule] = useState30([]);
|
|
5577
5674
|
const [busy, setBusy] = useState30(false);
|
|
5578
5675
|
const [error, setError] = useState30(null);
|
|
5676
|
+
const [step, setStep] = useState30({ kind: "idle" });
|
|
5677
|
+
const [reason, setReason] = useState30(null);
|
|
5678
|
+
const [comment, setComment] = useState30("");
|
|
5579
5679
|
const load = useCallback10(async () => {
|
|
5580
5680
|
if (!token) {
|
|
5581
5681
|
setSubscription(null);
|
|
@@ -5612,29 +5712,29 @@ function SubscriptionManager({
|
|
|
5612
5712
|
}
|
|
5613
5713
|
};
|
|
5614
5714
|
if (sessionLoading || loading) {
|
|
5615
|
-
return /* @__PURE__ */
|
|
5715
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
5616
5716
|
}
|
|
5617
5717
|
if (!token) {
|
|
5618
|
-
return /* @__PURE__ */
|
|
5718
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
|
|
5619
5719
|
}
|
|
5620
5720
|
if (error) {
|
|
5621
|
-
return /* @__PURE__ */
|
|
5721
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
|
|
5622
5722
|
}
|
|
5623
5723
|
if (!subscription) {
|
|
5624
|
-
return /* @__PURE__ */
|
|
5724
|
+
return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
|
|
5625
5725
|
}
|
|
5626
5726
|
const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
|
|
5627
5727
|
const next = schedule[0] ?? null;
|
|
5628
5728
|
const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
|
|
5629
|
-
return /* @__PURE__ */
|
|
5630
|
-
error ? /* @__PURE__ */
|
|
5631
|
-
/* @__PURE__ */
|
|
5632
|
-
/* @__PURE__ */
|
|
5729
|
+
return /* @__PURE__ */ jsxs31("div", { className: cls("b316-card", className), style, children: [
|
|
5730
|
+
error ? /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
5731
|
+
/* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
|
|
5732
|
+
/* @__PURE__ */ jsxs31("div", { className: "b316-muted", children: [
|
|
5633
5733
|
statusLabel(subscription.status),
|
|
5634
5734
|
" \xB7 ",
|
|
5635
5735
|
subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
|
|
5636
5736
|
] }),
|
|
5637
|
-
next && !managedBy ? /* @__PURE__ */
|
|
5737
|
+
next && !managedBy ? /* @__PURE__ */ jsxs31("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
|
|
5638
5738
|
"Moves to ",
|
|
5639
5739
|
next.plan.name,
|
|
5640
5740
|
" on ",
|
|
@@ -5642,7 +5742,7 @@ function SubscriptionManager({
|
|
|
5642
5742
|
". You keep ",
|
|
5643
5743
|
subscription.planVersion.plan.name,
|
|
5644
5744
|
" until then.",
|
|
5645
|
-
/* @__PURE__ */
|
|
5745
|
+
/* @__PURE__ */ jsx32("div", { children: /* @__PURE__ */ jsx32(
|
|
5646
5746
|
"button",
|
|
5647
5747
|
{
|
|
5648
5748
|
type: "button",
|
|
@@ -5667,17 +5767,17 @@ function SubscriptionManager({
|
|
|
5667
5767
|
}
|
|
5668
5768
|
) })
|
|
5669
5769
|
] }) : null,
|
|
5670
|
-
managedBy ? /* @__PURE__ */
|
|
5770
|
+
managedBy ? /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
|
|
5671
5771
|
"Provided by ",
|
|
5672
5772
|
managedBy.name ?? "the organization that manages your account",
|
|
5673
5773
|
". Ask them to change or cancel it."
|
|
5674
|
-
] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */
|
|
5675
|
-
/* @__PURE__ */
|
|
5774
|
+
] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ jsxs31("div", { children: [
|
|
5775
|
+
/* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
|
|
5676
5776
|
"This subscription will not renew. You keep access until ",
|
|
5677
5777
|
renews,
|
|
5678
5778
|
"."
|
|
5679
5779
|
] }),
|
|
5680
|
-
/* @__PURE__ */
|
|
5780
|
+
/* @__PURE__ */ jsx32(
|
|
5681
5781
|
"button",
|
|
5682
5782
|
{
|
|
5683
5783
|
type: "button",
|
|
@@ -5687,18 +5787,129 @@ function SubscriptionManager({
|
|
|
5687
5787
|
children: busy ? "Working\u2026" : "Resume subscription"
|
|
5688
5788
|
}
|
|
5689
5789
|
)
|
|
5690
|
-
] }) : /* @__PURE__ */
|
|
5691
|
-
|
|
5790
|
+
] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs31("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
|
|
5791
|
+
/* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
|
|
5792
|
+
/* @__PURE__ */ jsx32("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
|
|
5793
|
+
step.cancellation.offer,
|
|
5794
|
+
step.cancellation.currency
|
|
5795
|
+
)}.` }),
|
|
5796
|
+
/* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
5797
|
+
/* @__PURE__ */ jsx32(
|
|
5798
|
+
"button",
|
|
5799
|
+
{
|
|
5800
|
+
type: "button",
|
|
5801
|
+
className: "b316-button",
|
|
5802
|
+
disabled: busy,
|
|
5803
|
+
onClick: () => void act(async () => {
|
|
5804
|
+
await client.billing.acceptRetentionOffer(token, step.cancellation.id);
|
|
5805
|
+
setStep({ kind: "idle" });
|
|
5806
|
+
}, "Could not apply the offer. Try again."),
|
|
5807
|
+
children: busy ? "Working\u2026" : "Accept offer and stay"
|
|
5808
|
+
}
|
|
5809
|
+
),
|
|
5810
|
+
/* @__PURE__ */ jsx32(
|
|
5811
|
+
"button",
|
|
5812
|
+
{
|
|
5813
|
+
type: "button",
|
|
5814
|
+
className: "b316-button b316-button-secondary",
|
|
5815
|
+
disabled: busy,
|
|
5816
|
+
onClick: () => void act(async () => {
|
|
5817
|
+
await client.billing.confirmCancellation(token, step.cancellation.id);
|
|
5818
|
+
setStep({ kind: "idle" });
|
|
5819
|
+
}, "Could not cancel. Try again."),
|
|
5820
|
+
children: "No thanks, cancel"
|
|
5821
|
+
}
|
|
5822
|
+
)
|
|
5823
|
+
] }),
|
|
5824
|
+
/* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
|
|
5825
|
+
"If you cancel, you keep access until ",
|
|
5826
|
+
renews,
|
|
5827
|
+
"."
|
|
5828
|
+
] })
|
|
5829
|
+
] }) : step.kind === "survey" ? /* @__PURE__ */ jsxs31(
|
|
5830
|
+
"form",
|
|
5692
5831
|
{
|
|
5832
|
+
style: { marginTop: 14 },
|
|
5833
|
+
onSubmit: (event) => {
|
|
5834
|
+
event.preventDefault();
|
|
5835
|
+
void act(async () => {
|
|
5836
|
+
const started = await client.billing.startCancellation(token, {
|
|
5837
|
+
reason,
|
|
5838
|
+
comment: comment.trim() || null
|
|
5839
|
+
});
|
|
5840
|
+
if (started.offer) {
|
|
5841
|
+
setStep({ kind: "offer", cancellation: { ...started, offer: started.offer } });
|
|
5842
|
+
return;
|
|
5843
|
+
}
|
|
5844
|
+
await client.billing.confirmCancellation(token, started.id);
|
|
5845
|
+
setStep({ kind: "idle" });
|
|
5846
|
+
}, "Could not cancel. Try again.");
|
|
5847
|
+
},
|
|
5848
|
+
children: [
|
|
5849
|
+
/* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
|
|
5850
|
+
"You keep access until ",
|
|
5851
|
+
renews,
|
|
5852
|
+
". It will not renew after that."
|
|
5853
|
+
] }),
|
|
5854
|
+
/* @__PURE__ */ jsxs31("fieldset", { className: "b316-fieldset", children: [
|
|
5855
|
+
/* @__PURE__ */ jsx32("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
|
|
5856
|
+
REASONS.map((option) => /* @__PURE__ */ jsxs31("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
5857
|
+
/* @__PURE__ */ jsx32(
|
|
5858
|
+
"input",
|
|
5859
|
+
{
|
|
5860
|
+
type: "radio",
|
|
5861
|
+
name: "b316-cancel-reason",
|
|
5862
|
+
value: option.value,
|
|
5863
|
+
checked: reason === option.value,
|
|
5864
|
+
onChange: () => setReason(option.value)
|
|
5865
|
+
}
|
|
5866
|
+
),
|
|
5867
|
+
/* @__PURE__ */ jsx32("span", { children: option.label })
|
|
5868
|
+
] }, option.value))
|
|
5869
|
+
] }),
|
|
5870
|
+
/* @__PURE__ */ jsxs31("label", { className: "b316-field", children: [
|
|
5871
|
+
/* @__PURE__ */ jsx32("span", { className: "b316-label", children: "Anything else? (optional)" }),
|
|
5872
|
+
/* @__PURE__ */ jsx32(
|
|
5873
|
+
"textarea",
|
|
5874
|
+
{
|
|
5875
|
+
className: "b316-input",
|
|
5876
|
+
rows: 3,
|
|
5877
|
+
maxLength: 2e3,
|
|
5878
|
+
value: comment,
|
|
5879
|
+
onChange: (event) => setComment(event.target.value)
|
|
5880
|
+
}
|
|
5881
|
+
)
|
|
5882
|
+
] }),
|
|
5883
|
+
/* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
5884
|
+
/* @__PURE__ */ jsx32("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
|
|
5885
|
+
/* @__PURE__ */ jsxs31(
|
|
5886
|
+
"button",
|
|
5887
|
+
{
|
|
5888
|
+
type: "button",
|
|
5889
|
+
className: "b316-button",
|
|
5890
|
+
disabled: busy,
|
|
5891
|
+
onClick: () => setStep({ kind: "idle" }),
|
|
5892
|
+
children: [
|
|
5893
|
+
"Keep ",
|
|
5894
|
+
subscription.planVersion.plan.name
|
|
5895
|
+
]
|
|
5896
|
+
}
|
|
5897
|
+
)
|
|
5898
|
+
] })
|
|
5899
|
+
]
|
|
5900
|
+
}
|
|
5901
|
+
) : /* @__PURE__ */ jsx32("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx32(
|
|
5902
|
+
"button",
|
|
5903
|
+
{
|
|
5904
|
+
type: "button",
|
|
5693
5905
|
className: "b316-button b316-button-secondary",
|
|
5694
|
-
confirmLabel: `Cancel at the end of the period (${renews})`,
|
|
5695
5906
|
disabled: busy,
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
children:
|
|
5907
|
+
onClick: () => {
|
|
5908
|
+
setReason(null);
|
|
5909
|
+
setComment("");
|
|
5910
|
+
setStep({ kind: "survey" });
|
|
5911
|
+
},
|
|
5912
|
+
children: "Cancel subscription"
|
|
5702
5913
|
}
|
|
5703
5914
|
) })
|
|
5704
5915
|
] });
|
|
@@ -5709,7 +5920,7 @@ import { useCallback as useCallback12, useEffect as useEffect26, useState as use
|
|
|
5709
5920
|
|
|
5710
5921
|
// src/CreditBalances.tsx
|
|
5711
5922
|
import { useEffect as useEffect23, useState as useState31 } from "react";
|
|
5712
|
-
import { Fragment as Fragment9, jsx as
|
|
5923
|
+
import { Fragment as Fragment9, jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5713
5924
|
function units(value) {
|
|
5714
5925
|
return value === null ? "Unlimited" : Number(value).toLocaleString("en");
|
|
5715
5926
|
}
|
|
@@ -5801,33 +6012,33 @@ function Feature({
|
|
|
5801
6012
|
setBusy(false);
|
|
5802
6013
|
}
|
|
5803
6014
|
};
|
|
5804
|
-
return /* @__PURE__ */
|
|
5805
|
-
/* @__PURE__ */
|
|
5806
|
-
/* @__PURE__ */
|
|
5807
|
-
/* @__PURE__ */
|
|
6015
|
+
return /* @__PURE__ */ jsxs32("div", { className: "b316-card b316-credit-balance", children: [
|
|
6016
|
+
/* @__PURE__ */ jsx33("div", { className: "b316-label", children: feature.featureName }),
|
|
6017
|
+
/* @__PURE__ */ jsxs32("div", { children: [
|
|
6018
|
+
/* @__PURE__ */ jsx33("strong", { children: units(feature.remaining) }),
|
|
5808
6019
|
unit,
|
|
5809
6020
|
" left"
|
|
5810
6021
|
] }),
|
|
5811
|
-
/* @__PURE__ */
|
|
6022
|
+
/* @__PURE__ */ jsxs32("div", { className: "b316-muted", children: [
|
|
5812
6023
|
feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
|
|
5813
6024
|
" ",
|
|
5814
6025
|
"\xB7 ",
|
|
5815
6026
|
units(feature.purchasedRemaining),
|
|
5816
6027
|
" purchased"
|
|
5817
6028
|
] }),
|
|
5818
|
-
warning && !managed ? /* @__PURE__ */
|
|
5819
|
-
error ? /* @__PURE__ */
|
|
5820
|
-
saved ? /* @__PURE__ */
|
|
5821
|
-
managed || feature.packs.length === 0 ? null : /* @__PURE__ */
|
|
5822
|
-
/* @__PURE__ */
|
|
5823
|
-
/* @__PURE__ */
|
|
6029
|
+
warning && !managed ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: warning }) : null,
|
|
6030
|
+
error ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6031
|
+
saved ? /* @__PURE__ */ jsx33("div", { className: "b316-notice", role: "status", children: saved }) : null,
|
|
6032
|
+
managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs32(Fragment9, { children: [
|
|
6033
|
+
/* @__PURE__ */ jsxs32("div", { className: "b316-row", style: { marginTop: 12 }, children: [
|
|
6034
|
+
/* @__PURE__ */ jsx33(
|
|
5824
6035
|
"select",
|
|
5825
6036
|
{
|
|
5826
6037
|
className: "b316-input",
|
|
5827
6038
|
"aria-label": "Pack to buy",
|
|
5828
6039
|
value: pack,
|
|
5829
6040
|
onChange: (event) => setPack(event.target.value),
|
|
5830
|
-
children: feature.packs.map((option) => /* @__PURE__ */
|
|
6041
|
+
children: feature.packs.map((option) => /* @__PURE__ */ jsxs32("option", { value: option.id, children: [
|
|
5831
6042
|
option.name,
|
|
5832
6043
|
" \u2014 ",
|
|
5833
6044
|
units(option.units),
|
|
@@ -5836,7 +6047,7 @@ function Feature({
|
|
|
5836
6047
|
] }, option.id))
|
|
5837
6048
|
}
|
|
5838
6049
|
),
|
|
5839
|
-
/* @__PURE__ */
|
|
6050
|
+
/* @__PURE__ */ jsx33(
|
|
5840
6051
|
"button",
|
|
5841
6052
|
{
|
|
5842
6053
|
type: "button",
|
|
@@ -5847,19 +6058,19 @@ function Feature({
|
|
|
5847
6058
|
}
|
|
5848
6059
|
)
|
|
5849
6060
|
] }),
|
|
5850
|
-
/* @__PURE__ */
|
|
5851
|
-
/* @__PURE__ */
|
|
5852
|
-
/* @__PURE__ */
|
|
6061
|
+
/* @__PURE__ */ jsxs32("form", { onSubmit: save, style: { marginTop: 16 }, children: [
|
|
6062
|
+
/* @__PURE__ */ jsxs32("label", { className: "b316-checkbox", children: [
|
|
6063
|
+
/* @__PURE__ */ jsx33("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
|
|
5853
6064
|
" ",
|
|
5854
6065
|
"Buy credits automatically when my balance runs low"
|
|
5855
6066
|
] }),
|
|
5856
|
-
/* @__PURE__ */
|
|
5857
|
-
/* @__PURE__ */
|
|
6067
|
+
/* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
|
|
6068
|
+
/* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
|
|
5858
6069
|
"When fewer than this many",
|
|
5859
6070
|
unit,
|
|
5860
6071
|
" are left"
|
|
5861
6072
|
] }),
|
|
5862
|
-
/* @__PURE__ */
|
|
6073
|
+
/* @__PURE__ */ jsx33(
|
|
5863
6074
|
"input",
|
|
5864
6075
|
{
|
|
5865
6076
|
className: "b316-input",
|
|
@@ -5870,21 +6081,21 @@ function Feature({
|
|
|
5870
6081
|
}
|
|
5871
6082
|
)
|
|
5872
6083
|
] }),
|
|
5873
|
-
/* @__PURE__ */
|
|
5874
|
-
/* @__PURE__ */
|
|
5875
|
-
/* @__PURE__ */
|
|
6084
|
+
/* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
|
|
6085
|
+
/* @__PURE__ */ jsx33("span", { className: "b316-label", children: "Buy" }),
|
|
6086
|
+
/* @__PURE__ */ jsx33(
|
|
5876
6087
|
"select",
|
|
5877
6088
|
{
|
|
5878
6089
|
className: "b316-input",
|
|
5879
6090
|
name: "creditPackId",
|
|
5880
6091
|
defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
|
|
5881
|
-
children: feature.packs.map((option) => /* @__PURE__ */
|
|
6092
|
+
children: feature.packs.map((option) => /* @__PURE__ */ jsx33("option", { value: option.id, children: option.name }, option.id))
|
|
5882
6093
|
}
|
|
5883
6094
|
)
|
|
5884
6095
|
] }),
|
|
5885
|
-
/* @__PURE__ */
|
|
5886
|
-
/* @__PURE__ */
|
|
5887
|
-
/* @__PURE__ */
|
|
6096
|
+
/* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
|
|
6097
|
+
/* @__PURE__ */ jsx33("span", { className: "b316-label", children: "At most this many times a month" }),
|
|
6098
|
+
/* @__PURE__ */ jsx33(
|
|
5888
6099
|
"input",
|
|
5889
6100
|
{
|
|
5890
6101
|
className: "b316-input",
|
|
@@ -5894,13 +6105,13 @@ function Feature({
|
|
|
5894
6105
|
}
|
|
5895
6106
|
)
|
|
5896
6107
|
] }),
|
|
5897
|
-
/* @__PURE__ */
|
|
5898
|
-
/* @__PURE__ */
|
|
6108
|
+
/* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
|
|
6109
|
+
/* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
|
|
5899
6110
|
"Spending at most (",
|
|
5900
6111
|
setting?.currency ?? feature.packs[0]?.currency ?? "USD",
|
|
5901
6112
|
") a month"
|
|
5902
6113
|
] }),
|
|
5903
|
-
/* @__PURE__ */
|
|
6114
|
+
/* @__PURE__ */ jsx33(
|
|
5904
6115
|
"input",
|
|
5905
6116
|
{
|
|
5906
6117
|
className: "b316-input",
|
|
@@ -5910,7 +6121,7 @@ function Feature({
|
|
|
5910
6121
|
}
|
|
5911
6122
|
)
|
|
5912
6123
|
] }),
|
|
5913
|
-
/* @__PURE__ */
|
|
6124
|
+
/* @__PURE__ */ jsx33("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
|
|
5914
6125
|
] })
|
|
5915
6126
|
] })
|
|
5916
6127
|
] });
|
|
@@ -5932,24 +6143,24 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
5932
6143
|
cancelled = true;
|
|
5933
6144
|
};
|
|
5934
6145
|
}, [client, token, version]);
|
|
5935
|
-
const wrap = (content) => /* @__PURE__ */
|
|
6146
|
+
const wrap = (content) => /* @__PURE__ */ jsx33("div", { className: cls("b316-credit-balances", className), style, children: content });
|
|
5936
6147
|
if (sessionLoading || !token || state.kind === "loading") return null;
|
|
5937
6148
|
if (state.kind === "error") {
|
|
5938
6149
|
return wrap(
|
|
5939
|
-
/* @__PURE__ */
|
|
6150
|
+
/* @__PURE__ */ jsx33("div", { className: "b316-card", children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
|
|
5940
6151
|
);
|
|
5941
6152
|
}
|
|
5942
6153
|
const { credits } = state;
|
|
5943
6154
|
if (credits.features.length === 0) return null;
|
|
5944
6155
|
return wrap(
|
|
5945
|
-
/* @__PURE__ */
|
|
5946
|
-
credits.managedBy ? /* @__PURE__ */
|
|
6156
|
+
/* @__PURE__ */ jsxs32(Fragment9, { children: [
|
|
6157
|
+
credits.managedBy ? /* @__PURE__ */ jsxs32("p", { className: "b316-muted", children: [
|
|
5947
6158
|
"Credits for this account come from",
|
|
5948
6159
|
" ",
|
|
5949
6160
|
credits.managedBy.name ?? "the organization that manages it",
|
|
5950
6161
|
", which manages them."
|
|
5951
6162
|
] }) : null,
|
|
5952
|
-
credits.features.map((feature) => /* @__PURE__ */
|
|
6163
|
+
credits.features.map((feature) => /* @__PURE__ */ jsx33(
|
|
5953
6164
|
Feature,
|
|
5954
6165
|
{
|
|
5955
6166
|
feature,
|
|
@@ -5967,7 +6178,7 @@ function CreditBalances({ onChange, className, style }) {
|
|
|
5967
6178
|
|
|
5968
6179
|
// src/PaymentMethod.tsx
|
|
5969
6180
|
import { useEffect as useEffect24, useState as useState32 } from "react";
|
|
5970
|
-
import { Fragment as Fragment10, jsx as
|
|
6181
|
+
import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5971
6182
|
function brandName(brand) {
|
|
5972
6183
|
if (!brand) return "Card";
|
|
5973
6184
|
return brand.charAt(0).toUpperCase() + brand.slice(1);
|
|
@@ -5994,7 +6205,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
5994
6205
|
cancelled = true;
|
|
5995
6206
|
};
|
|
5996
6207
|
}, [client, token, version]);
|
|
5997
|
-
const wrap = (content) => /* @__PURE__ */
|
|
6208
|
+
const wrap = (content) => /* @__PURE__ */ jsx34("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
|
|
5998
6209
|
if (sessionLoading) return wrap("Loading\u2026");
|
|
5999
6210
|
if (!token) return wrap("Sign in to manage your payment method.");
|
|
6000
6211
|
switch (state.kind) {
|
|
@@ -6002,11 +6213,11 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6002
6213
|
return wrap("Loading\u2026");
|
|
6003
6214
|
case "error":
|
|
6004
6215
|
return wrap(
|
|
6005
|
-
/* @__PURE__ */
|
|
6216
|
+
/* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
|
|
6006
6217
|
);
|
|
6007
6218
|
case "managed":
|
|
6008
6219
|
return wrap(
|
|
6009
|
-
/* @__PURE__ */
|
|
6220
|
+
/* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
|
|
6010
6221
|
);
|
|
6011
6222
|
}
|
|
6012
6223
|
const card = state.cards.find((saved) => saved.isDefault) ?? null;
|
|
@@ -6025,31 +6236,31 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6025
6236
|
}
|
|
6026
6237
|
};
|
|
6027
6238
|
return wrap(
|
|
6028
|
-
/* @__PURE__ */
|
|
6029
|
-
/* @__PURE__ */
|
|
6030
|
-
card ? /* @__PURE__ */
|
|
6031
|
-
/* @__PURE__ */
|
|
6239
|
+
/* @__PURE__ */ jsxs33(Fragment10, { children: [
|
|
6240
|
+
/* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Payment method" }),
|
|
6241
|
+
card ? /* @__PURE__ */ jsxs33("div", { children: [
|
|
6242
|
+
/* @__PURE__ */ jsxs33("div", { children: [
|
|
6032
6243
|
brandName(card.brand),
|
|
6033
6244
|
" ending ",
|
|
6034
6245
|
card.last4 ?? "????"
|
|
6035
6246
|
] }),
|
|
6036
|
-
card.expMonth && card.expYear ? /* @__PURE__ */
|
|
6247
|
+
card.expMonth && card.expYear ? /* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
|
|
6037
6248
|
"Expires ",
|
|
6038
6249
|
String(card.expMonth).padStart(2, "0"),
|
|
6039
6250
|
"/",
|
|
6040
6251
|
card.expYear
|
|
6041
6252
|
] }) : null
|
|
6042
|
-
] }) : /* @__PURE__ */
|
|
6043
|
-
others.length > 0 ? /* @__PURE__ */
|
|
6044
|
-
/* @__PURE__ */
|
|
6045
|
-
others.map((saved) => /* @__PURE__ */
|
|
6046
|
-
/* @__PURE__ */
|
|
6253
|
+
] }) : /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "No card on file." }),
|
|
6254
|
+
others.length > 0 ? /* @__PURE__ */ jsxs33("div", { style: { marginTop: 12 }, children: [
|
|
6255
|
+
/* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Other saved cards" }),
|
|
6256
|
+
others.map((saved) => /* @__PURE__ */ jsxs33("div", { className: "b316-row", style: { marginTop: 6 }, children: [
|
|
6257
|
+
/* @__PURE__ */ jsxs33("span", { children: [
|
|
6047
6258
|
brandName(saved.brand),
|
|
6048
6259
|
" ending ",
|
|
6049
6260
|
saved.last4 ?? "????"
|
|
6050
6261
|
] }),
|
|
6051
|
-
/* @__PURE__ */
|
|
6052
|
-
/* @__PURE__ */
|
|
6262
|
+
/* @__PURE__ */ jsxs33("span", { children: [
|
|
6263
|
+
/* @__PURE__ */ jsx34(
|
|
6053
6264
|
"button",
|
|
6054
6265
|
{
|
|
6055
6266
|
type: "button",
|
|
@@ -6063,7 +6274,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6063
6274
|
}
|
|
6064
6275
|
),
|
|
6065
6276
|
" ",
|
|
6066
|
-
/* @__PURE__ */
|
|
6277
|
+
/* @__PURE__ */ jsx34(
|
|
6067
6278
|
"button",
|
|
6068
6279
|
{
|
|
6069
6280
|
type: "button",
|
|
@@ -6079,8 +6290,8 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6079
6290
|
] })
|
|
6080
6291
|
] }, saved.id))
|
|
6081
6292
|
] }) : null,
|
|
6082
|
-
error ? /* @__PURE__ */
|
|
6083
|
-
/* @__PURE__ */
|
|
6293
|
+
error ? /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6294
|
+
/* @__PURE__ */ jsx34(
|
|
6084
6295
|
"button",
|
|
6085
6296
|
{
|
|
6086
6297
|
type: "button",
|
|
@@ -6110,7 +6321,7 @@ function PaymentMethod({ returnUrl, className, style }) {
|
|
|
6110
6321
|
|
|
6111
6322
|
// src/PlanChangeReview.tsx
|
|
6112
6323
|
import { useCallback as useCallback11, useEffect as useEffect25, useState as useState33 } from "react";
|
|
6113
|
-
import { Fragment as Fragment11, jsx as
|
|
6324
|
+
import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6114
6325
|
function money5(amount, currency) {
|
|
6115
6326
|
if (amount === null) return "\u2014";
|
|
6116
6327
|
const value = Number(amount);
|
|
@@ -6200,12 +6411,12 @@ function PlanChangeReview({
|
|
|
6200
6411
|
setError("Cards cannot be added here right now.");
|
|
6201
6412
|
}
|
|
6202
6413
|
}, [client, token, onNeedsCard]);
|
|
6203
|
-
const card = (content) => /* @__PURE__ */
|
|
6414
|
+
const card = (content) => /* @__PURE__ */ jsx35("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
|
|
6204
6415
|
if (error && !preview) {
|
|
6205
6416
|
return card(
|
|
6206
|
-
/* @__PURE__ */
|
|
6207
|
-
/* @__PURE__ */
|
|
6208
|
-
onCancel ? /* @__PURE__ */
|
|
6417
|
+
/* @__PURE__ */ jsxs34(Fragment11, { children: [
|
|
6418
|
+
/* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }),
|
|
6419
|
+
onCancel ? /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
|
|
6209
6420
|
] })
|
|
6210
6421
|
);
|
|
6211
6422
|
}
|
|
@@ -6218,26 +6429,26 @@ function PlanChangeReview({
|
|
|
6218
6429
|
const otherReason = preview.timings[other]?.reason ?? null;
|
|
6219
6430
|
const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
|
|
6220
6431
|
return card(
|
|
6221
|
-
/* @__PURE__ */
|
|
6222
|
-
/* @__PURE__ */
|
|
6432
|
+
/* @__PURE__ */ jsxs34(Fragment11, { children: [
|
|
6433
|
+
/* @__PURE__ */ jsxs34("div", { className: "b316-plan-name", children: [
|
|
6223
6434
|
"Change to ",
|
|
6224
6435
|
to.planName
|
|
6225
6436
|
] }),
|
|
6226
|
-
/* @__PURE__ */
|
|
6437
|
+
/* @__PURE__ */ jsxs34("div", { className: "b316-muted", children: [
|
|
6227
6438
|
"From ",
|
|
6228
6439
|
from.planName
|
|
6229
6440
|
] }),
|
|
6230
|
-
error ? /* @__PURE__ */
|
|
6231
|
-
changes.length === 0 ? /* @__PURE__ */
|
|
6232
|
-
/* @__PURE__ */
|
|
6233
|
-
/* @__PURE__ */
|
|
6234
|
-
/* @__PURE__ */
|
|
6235
|
-
/* @__PURE__ */
|
|
6441
|
+
error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6442
|
+
changes.length === 0 ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs34("table", { className: "b316-review-table", children: [
|
|
6443
|
+
/* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs34("tr", { children: [
|
|
6444
|
+
/* @__PURE__ */ jsx35("th", { children: "Feature" }),
|
|
6445
|
+
/* @__PURE__ */ jsx35("th", { children: from.planName }),
|
|
6446
|
+
/* @__PURE__ */ jsx35("th", { children: to.planName })
|
|
6236
6447
|
] }) }),
|
|
6237
|
-
/* @__PURE__ */
|
|
6238
|
-
/* @__PURE__ */
|
|
6239
|
-
/* @__PURE__ */
|
|
6240
|
-
/* @__PURE__ */
|
|
6448
|
+
/* @__PURE__ */ jsx35("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs34("tr", { children: [
|
|
6449
|
+
/* @__PURE__ */ jsx35("td", { children: change.featureName }),
|
|
6450
|
+
/* @__PURE__ */ jsx35("td", { children: limitText(change.before, change.type) }),
|
|
6451
|
+
/* @__PURE__ */ jsx35(
|
|
6241
6452
|
"td",
|
|
6242
6453
|
{
|
|
6243
6454
|
className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
|
|
@@ -6246,40 +6457,40 @@ function PlanChangeReview({
|
|
|
6246
6457
|
)
|
|
6247
6458
|
] }, change.featureId)) })
|
|
6248
6459
|
] }),
|
|
6249
|
-
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */
|
|
6460
|
+
preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ jsxs34("p", { children: [
|
|
6250
6461
|
"The change happens now. Your trial carries on until ",
|
|
6251
6462
|
day4(now.trialEndsAt),
|
|
6252
6463
|
", and nothing is charged before then."
|
|
6253
|
-
] }) : /* @__PURE__ */
|
|
6254
|
-
Number(now.credit) > 0 ? /* @__PURE__ */
|
|
6255
|
-
/* @__PURE__ */
|
|
6464
|
+
] }) : /* @__PURE__ */ jsxs34("div", { children: [
|
|
6465
|
+
Number(now.credit) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
|
|
6466
|
+
/* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
|
|
6256
6467
|
"Credit for the unused part of ",
|
|
6257
6468
|
from.planName
|
|
6258
6469
|
] }),
|
|
6259
|
-
/* @__PURE__ */
|
|
6470
|
+
/* @__PURE__ */ jsxs34("span", { className: "b316-num", children: [
|
|
6260
6471
|
"\u2212",
|
|
6261
6472
|
money5(now.credit, from.currency)
|
|
6262
6473
|
] })
|
|
6263
6474
|
] }) : null,
|
|
6264
|
-
Number(now.closingUsage) > 0 ? /* @__PURE__ */
|
|
6265
|
-
/* @__PURE__ */
|
|
6266
|
-
/* @__PURE__ */
|
|
6475
|
+
Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
|
|
6476
|
+
/* @__PURE__ */ jsx35("span", { className: "b316-muted", children: "Usage so far this period" }),
|
|
6477
|
+
/* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
|
|
6267
6478
|
] }) : null,
|
|
6268
|
-
/* @__PURE__ */
|
|
6269
|
-
/* @__PURE__ */
|
|
6479
|
+
/* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
|
|
6480
|
+
/* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
|
|
6270
6481
|
to.planName,
|
|
6271
6482
|
", ",
|
|
6272
6483
|
day4(now.newPeriod.start),
|
|
6273
6484
|
" \u2013 ",
|
|
6274
6485
|
day4(now.newPeriod.end)
|
|
6275
6486
|
] }),
|
|
6276
|
-
/* @__PURE__ */
|
|
6487
|
+
/* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
|
|
6277
6488
|
] }),
|
|
6278
|
-
now.net !== null ? /* @__PURE__ */
|
|
6279
|
-
/* @__PURE__ */
|
|
6280
|
-
/* @__PURE__ */
|
|
6489
|
+
now.net !== null ? /* @__PURE__ */ jsxs34("div", { className: "b316-row b316-invoice-total", children: [
|
|
6490
|
+
/* @__PURE__ */ jsx35("span", { children: "Due now" }),
|
|
6491
|
+
/* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.net, to.currency) })
|
|
6281
6492
|
] }) : null
|
|
6282
|
-
] }) : /* @__PURE__ */
|
|
6493
|
+
] }) : /* @__PURE__ */ jsxs34("p", { children: [
|
|
6283
6494
|
"You keep ",
|
|
6284
6495
|
from.planName,
|
|
6285
6496
|
" until ",
|
|
@@ -6292,7 +6503,7 @@ function PlanChangeReview({
|
|
|
6292
6503
|
preview.atPeriodEnd.nextInvoice.currency
|
|
6293
6504
|
)}.` : ""
|
|
6294
6505
|
] }),
|
|
6295
|
-
otherOpen ? /* @__PURE__ */
|
|
6506
|
+
otherOpen ? /* @__PURE__ */ jsx35(
|
|
6296
6507
|
"button",
|
|
6297
6508
|
{
|
|
6298
6509
|
type: "button",
|
|
@@ -6303,12 +6514,12 @@ function PlanChangeReview({
|
|
|
6303
6514
|
},
|
|
6304
6515
|
children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
|
|
6305
6516
|
}
|
|
6306
|
-
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */
|
|
6307
|
-
needsCard ? /* @__PURE__ */
|
|
6517
|
+
) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
|
|
6518
|
+
needsCard ? /* @__PURE__ */ jsxs34("div", { className: "b316-notice", role: "status", children: [
|
|
6308
6519
|
"A card is needed for a change that is charged now.",
|
|
6309
|
-
/* @__PURE__ */
|
|
6310
|
-
] }) : /* @__PURE__ */
|
|
6311
|
-
/* @__PURE__ */
|
|
6520
|
+
/* @__PURE__ */ jsx35("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
|
|
6521
|
+
] }) : /* @__PURE__ */ jsxs34("div", { className: "b316-review-actions", children: [
|
|
6522
|
+
/* @__PURE__ */ jsx35(
|
|
6312
6523
|
"button",
|
|
6313
6524
|
{
|
|
6314
6525
|
type: "button",
|
|
@@ -6318,7 +6529,7 @@ function PlanChangeReview({
|
|
|
6318
6529
|
children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
|
|
6319
6530
|
}
|
|
6320
6531
|
),
|
|
6321
|
-
onCancel ? /* @__PURE__ */
|
|
6532
|
+
onCancel ? /* @__PURE__ */ jsxs34("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
|
|
6322
6533
|
"Keep ",
|
|
6323
6534
|
from.planName
|
|
6324
6535
|
] }) : null
|
|
@@ -6328,7 +6539,7 @@ function PlanChangeReview({
|
|
|
6328
6539
|
}
|
|
6329
6540
|
|
|
6330
6541
|
// src/BillingPortal.tsx
|
|
6331
|
-
import { Fragment as Fragment12, jsx as
|
|
6542
|
+
import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6332
6543
|
function BillingPortal({
|
|
6333
6544
|
returnUrl,
|
|
6334
6545
|
featuredPlanKey,
|
|
@@ -6366,24 +6577,24 @@ function BillingPortal({
|
|
|
6366
6577
|
setNotice(null);
|
|
6367
6578
|
setVersion((value) => value + 1);
|
|
6368
6579
|
}, []);
|
|
6369
|
-
const shell = (content) => /* @__PURE__ */
|
|
6370
|
-
if (sessionLoading) return shell(/* @__PURE__ */
|
|
6371
|
-
if (!token) return shell(/* @__PURE__ */
|
|
6580
|
+
const shell = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-billing-portal", className), style, children: content });
|
|
6581
|
+
if (sessionLoading) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6582
|
+
if (!token) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Sign in to manage your billing." }));
|
|
6372
6583
|
if (failed) {
|
|
6373
6584
|
return shell(
|
|
6374
|
-
/* @__PURE__ */
|
|
6585
|
+
/* @__PURE__ */ jsx36("div", { className: "b316-card", children: /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
|
|
6375
6586
|
);
|
|
6376
6587
|
}
|
|
6377
|
-
if (!overview) return shell(/* @__PURE__ */
|
|
6588
|
+
if (!overview) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
|
|
6378
6589
|
const { subscription, managedBy, quantityPriced } = overview;
|
|
6379
6590
|
const canChange = Boolean(subscription) && !managedBy;
|
|
6380
6591
|
return shell(
|
|
6381
|
-
/* @__PURE__ */
|
|
6382
|
-
notice ? /* @__PURE__ */
|
|
6383
|
-
/* @__PURE__ */
|
|
6384
|
-
canChange ? /* @__PURE__ */
|
|
6385
|
-
canChange && quantityPriced ? /* @__PURE__ */
|
|
6386
|
-
reviewing ? /* @__PURE__ */
|
|
6592
|
+
/* @__PURE__ */ jsxs35(Fragment12, { children: [
|
|
6593
|
+
notice ? /* @__PURE__ */ jsx36("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
|
|
6594
|
+
/* @__PURE__ */ jsx36(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
|
|
6595
|
+
canChange ? /* @__PURE__ */ jsx36(UpcomingInvoice, {}, `next-${version}`) : null,
|
|
6596
|
+
canChange && quantityPriced ? /* @__PURE__ */ jsx36(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
|
|
6597
|
+
reviewing ? /* @__PURE__ */ jsx36(
|
|
6387
6598
|
PlanChangeReview,
|
|
6388
6599
|
{
|
|
6389
6600
|
planVersionId: reviewing,
|
|
@@ -6396,9 +6607,9 @@ function BillingPortal({
|
|
|
6396
6607
|
);
|
|
6397
6608
|
}
|
|
6398
6609
|
}
|
|
6399
|
-
) : /* @__PURE__ */
|
|
6400
|
-
/* @__PURE__ */
|
|
6401
|
-
/* @__PURE__ */
|
|
6610
|
+
) : /* @__PURE__ */ jsxs35("section", { children: [
|
|
6611
|
+
/* @__PURE__ */ jsx36("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
|
|
6612
|
+
/* @__PURE__ */ jsx36(
|
|
6402
6613
|
PricingTable,
|
|
6403
6614
|
{
|
|
6404
6615
|
featuredPlanKey,
|
|
@@ -6410,17 +6621,17 @@ function BillingPortal({
|
|
|
6410
6621
|
`plans-${version}`
|
|
6411
6622
|
)
|
|
6412
6623
|
] }),
|
|
6413
|
-
/* @__PURE__ */
|
|
6414
|
-
managedBy ? null : /* @__PURE__ */
|
|
6415
|
-
/* @__PURE__ */
|
|
6416
|
-
billingDetails === void 0 ? /* @__PURE__ */
|
|
6624
|
+
/* @__PURE__ */ jsx36(CreditBalances, {}, `credits-${version}`),
|
|
6625
|
+
managedBy ? null : /* @__PURE__ */ jsx36(PaymentMethod, { returnUrl }, `card-${version}`),
|
|
6626
|
+
/* @__PURE__ */ jsx36(Invoices, {}, `invoices-${version}`),
|
|
6627
|
+
billingDetails === void 0 ? /* @__PURE__ */ jsx36(BillingDetailsForm, {}, `details-${version}`) : billingDetails
|
|
6417
6628
|
] })
|
|
6418
6629
|
);
|
|
6419
6630
|
}
|
|
6420
6631
|
|
|
6421
6632
|
// src/ApiKeyManager.tsx
|
|
6422
6633
|
import { useCallback as useCallback13, useEffect as useEffect27, useState as useState35 } from "react";
|
|
6423
|
-
import { jsx as
|
|
6634
|
+
import { jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
6424
6635
|
function duration(seconds) {
|
|
6425
6636
|
if (seconds % 3600 === 0) {
|
|
6426
6637
|
return `${seconds / 3600}h`;
|
|
@@ -6472,16 +6683,16 @@ function ApiKeyManager({
|
|
|
6472
6683
|
void load();
|
|
6473
6684
|
}, [load]);
|
|
6474
6685
|
if (sessionLoading || loading) {
|
|
6475
|
-
return /* @__PURE__ */
|
|
6686
|
+
return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
|
|
6476
6687
|
}
|
|
6477
6688
|
if (!token) {
|
|
6478
|
-
return /* @__PURE__ */
|
|
6689
|
+
return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
|
|
6479
6690
|
}
|
|
6480
6691
|
if (error) {
|
|
6481
|
-
return /* @__PURE__ */
|
|
6692
|
+
return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) });
|
|
6482
6693
|
}
|
|
6483
6694
|
if (resources.length === 0) {
|
|
6484
|
-
return /* @__PURE__ */
|
|
6695
|
+
return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
|
|
6485
6696
|
}
|
|
6486
6697
|
const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
|
|
6487
6698
|
const reset = () => {
|
|
@@ -6490,37 +6701,37 @@ function ApiKeyManager({
|
|
|
6490
6701
|
setChosen([]);
|
|
6491
6702
|
setIssued(null);
|
|
6492
6703
|
};
|
|
6493
|
-
return /* @__PURE__ */
|
|
6494
|
-
error ? /* @__PURE__ */
|
|
6495
|
-
resources.length > 1 ? /* @__PURE__ */
|
|
6704
|
+
return /* @__PURE__ */ jsxs36("div", { className: cls("b316-card", className), style, children: [
|
|
6705
|
+
error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
|
|
6706
|
+
resources.length > 1 ? /* @__PURE__ */ jsx37(
|
|
6496
6707
|
"select",
|
|
6497
6708
|
{
|
|
6498
6709
|
className: "b316-input",
|
|
6499
6710
|
value: resource.id,
|
|
6500
6711
|
onChange: (event) => setResourceId(event.target.value),
|
|
6501
6712
|
style: { marginBottom: 14 },
|
|
6502
|
-
children: resources.map((item) => /* @__PURE__ */
|
|
6713
|
+
children: resources.map((item) => /* @__PURE__ */ jsx37("option", { value: item.id, children: item.name }, item.id))
|
|
6503
6714
|
}
|
|
6504
|
-
) : /* @__PURE__ */
|
|
6505
|
-
resource.rateLimit ? /* @__PURE__ */
|
|
6715
|
+
) : /* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: resource.name }),
|
|
6716
|
+
resource.rateLimit ? /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
|
|
6506
6717
|
resource.rateLimit.requestsPerWindow,
|
|
6507
6718
|
" requests per",
|
|
6508
6719
|
" ",
|
|
6509
6720
|
duration(resource.rateLimit.windowSeconds),
|
|
6510
6721
|
resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
|
|
6511
|
-
] }) : /* @__PURE__ */
|
|
6512
|
-
credentials.length === 0 ? /* @__PURE__ */
|
|
6513
|
-
/* @__PURE__ */
|
|
6514
|
-
/* @__PURE__ */
|
|
6515
|
-
/* @__PURE__ */
|
|
6516
|
-
/* @__PURE__ */
|
|
6722
|
+
] }) : /* @__PURE__ */ jsx37("div", { className: "b316-muted", children: "No rate limit." }),
|
|
6723
|
+
credentials.length === 0 ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx37("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs36("li", { className: "b316-list-item", children: [
|
|
6724
|
+
/* @__PURE__ */ jsxs36("div", { children: [
|
|
6725
|
+
/* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: credential.name }),
|
|
6726
|
+
/* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
|
|
6727
|
+
/* @__PURE__ */ jsx37("code", { children: credential.clientId }),
|
|
6517
6728
|
credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
|
|
6518
6729
|
credential.disabled ? " \xB7 Disabled" : null
|
|
6519
6730
|
] }),
|
|
6520
|
-
/* @__PURE__ */
|
|
6731
|
+
/* @__PURE__ */ jsx37("div", { className: "b316-muted", children: credential.scopes.join(", ") })
|
|
6521
6732
|
] }),
|
|
6522
|
-
/* @__PURE__ */
|
|
6523
|
-
/* @__PURE__ */
|
|
6733
|
+
/* @__PURE__ */ jsxs36("div", { style: { display: "flex", gap: 8 }, children: [
|
|
6734
|
+
/* @__PURE__ */ jsx37(
|
|
6524
6735
|
"button",
|
|
6525
6736
|
{
|
|
6526
6737
|
type: "button",
|
|
@@ -6549,7 +6760,7 @@ function ApiKeyManager({
|
|
|
6549
6760
|
children: "Rotate"
|
|
6550
6761
|
}
|
|
6551
6762
|
),
|
|
6552
|
-
/* @__PURE__ */
|
|
6763
|
+
/* @__PURE__ */ jsx37(
|
|
6553
6764
|
ConfirmButton,
|
|
6554
6765
|
{
|
|
6555
6766
|
className: "b316-button b316-button-secondary",
|
|
@@ -6573,11 +6784,11 @@ function ApiKeyManager({
|
|
|
6573
6784
|
)
|
|
6574
6785
|
] })
|
|
6575
6786
|
] }, credential.clientId)) }),
|
|
6576
|
-
issued ? /* @__PURE__ */
|
|
6577
|
-
/* @__PURE__ */
|
|
6787
|
+
issued ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
|
|
6788
|
+
/* @__PURE__ */ jsx37("strong", { children: "Copy this now." }),
|
|
6578
6789
|
" It is shown once and cannot be retrieved again.",
|
|
6579
|
-
/* @__PURE__ */
|
|
6580
|
-
/* @__PURE__ */
|
|
6790
|
+
/* @__PURE__ */ jsx37("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx37("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
|
|
6791
|
+
/* @__PURE__ */ jsx37(
|
|
6581
6792
|
"button",
|
|
6582
6793
|
{
|
|
6583
6794
|
type: "button",
|
|
@@ -6590,7 +6801,7 @@ function ApiKeyManager({
|
|
|
6590
6801
|
children: "Copy"
|
|
6591
6802
|
}
|
|
6592
6803
|
),
|
|
6593
|
-
/* @__PURE__ */
|
|
6804
|
+
/* @__PURE__ */ jsx37(
|
|
6594
6805
|
"button",
|
|
6595
6806
|
{
|
|
6596
6807
|
type: "button",
|
|
@@ -6601,8 +6812,8 @@ function ApiKeyManager({
|
|
|
6601
6812
|
}
|
|
6602
6813
|
)
|
|
6603
6814
|
] }) : null,
|
|
6604
|
-
creating && !issued ? /* @__PURE__ */
|
|
6605
|
-
/* @__PURE__ */
|
|
6815
|
+
creating && !issued ? /* @__PURE__ */ jsxs36("div", { style: { marginTop: 14 }, children: [
|
|
6816
|
+
/* @__PURE__ */ jsx37(
|
|
6606
6817
|
"input",
|
|
6607
6818
|
{
|
|
6608
6819
|
className: "b316-input",
|
|
@@ -6611,9 +6822,9 @@ function ApiKeyManager({
|
|
|
6611
6822
|
onChange: (event) => setName(event.target.value)
|
|
6612
6823
|
}
|
|
6613
6824
|
),
|
|
6614
|
-
/* @__PURE__ */
|
|
6615
|
-
resource.availableScopes.map((scope) => /* @__PURE__ */
|
|
6616
|
-
/* @__PURE__ */
|
|
6825
|
+
/* @__PURE__ */ jsxs36("div", { style: { marginTop: 10 }, children: [
|
|
6826
|
+
resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox", children: [
|
|
6827
|
+
/* @__PURE__ */ jsx37(
|
|
6617
6828
|
"input",
|
|
6618
6829
|
{
|
|
6619
6830
|
type: "checkbox",
|
|
@@ -6623,19 +6834,19 @@ function ApiKeyManager({
|
|
|
6623
6834
|
)
|
|
6624
6835
|
}
|
|
6625
6836
|
),
|
|
6626
|
-
/* @__PURE__ */
|
|
6627
|
-
scope.description ? /* @__PURE__ */
|
|
6837
|
+
/* @__PURE__ */ jsx37("code", { children: scope.key }),
|
|
6838
|
+
scope.description ? /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
|
|
6628
6839
|
" \u2014 ",
|
|
6629
6840
|
scope.description
|
|
6630
6841
|
] }) : null
|
|
6631
6842
|
] }, scope.key)),
|
|
6632
|
-
resource.lockedScopes.map((scope) => /* @__PURE__ */
|
|
6633
|
-
/* @__PURE__ */
|
|
6634
|
-
/* @__PURE__ */
|
|
6635
|
-
/* @__PURE__ */
|
|
6843
|
+
resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox b316-muted", children: [
|
|
6844
|
+
/* @__PURE__ */ jsx37("input", { type: "checkbox", disabled: true }),
|
|
6845
|
+
/* @__PURE__ */ jsx37("code", { children: scope.key }),
|
|
6846
|
+
/* @__PURE__ */ jsx37("span", { children: " \u2014 not included in your plan" })
|
|
6636
6847
|
] }, scope.key))
|
|
6637
6848
|
] }),
|
|
6638
|
-
/* @__PURE__ */
|
|
6849
|
+
/* @__PURE__ */ jsx37(
|
|
6639
6850
|
"button",
|
|
6640
6851
|
{
|
|
6641
6852
|
type: "button",
|
|
@@ -6669,7 +6880,7 @@ function ApiKeyManager({
|
|
|
6669
6880
|
children: "Create key"
|
|
6670
6881
|
}
|
|
6671
6882
|
),
|
|
6672
|
-
/* @__PURE__ */
|
|
6883
|
+
/* @__PURE__ */ jsx37(
|
|
6673
6884
|
"button",
|
|
6674
6885
|
{
|
|
6675
6886
|
type: "button",
|
|
@@ -6680,7 +6891,7 @@ function ApiKeyManager({
|
|
|
6680
6891
|
}
|
|
6681
6892
|
)
|
|
6682
6893
|
] }) : null,
|
|
6683
|
-
!creating && !issued ? /* @__PURE__ */
|
|
6894
|
+
!creating && !issued ? /* @__PURE__ */ jsx37(
|
|
6684
6895
|
"button",
|
|
6685
6896
|
{
|
|
6686
6897
|
type: "button",
|
|
@@ -6964,7 +7175,7 @@ var MANIFEST = [
|
|
|
6964
7175
|
{
|
|
6965
7176
|
name: "TwoFactorManager",
|
|
6966
7177
|
kind: "component",
|
|
6967
|
-
summary: "Turn two-factor authentication on or off, by authenticator app, a code to the inbox or a code by text message.",
|
|
7178
|
+
summary: "Turn two-factor authentication on or off, by authenticator app (QR code and key), a code to the inbox or a code by text message.",
|
|
6968
7179
|
useWhen: "A security settings page. The app is strongest; the emailed or texted code is the one people who will not install an app actually use.",
|
|
6969
7180
|
requires: ["session"],
|
|
6970
7181
|
props: [
|
|
@@ -7108,7 +7319,7 @@ var MANIFEST = [
|
|
|
7108
7319
|
{
|
|
7109
7320
|
name: "SubscriptionManager",
|
|
7110
7321
|
kind: "component",
|
|
7111
|
-
summary: "The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end
|
|
7322
|
+
summary: "The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end \u2014 asking why, and showing the environment's retention offer when it makes one \u2014 and resuming a cancelled one.",
|
|
7112
7323
|
useWhen: "A billing settings page.",
|
|
7113
7324
|
requires: ["session"],
|
|
7114
7325
|
props: [
|