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