cauthy-auth 0.36.1 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/dist/client.d.mts +2 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.js.map +1 -1
- package/dist/client.mjs.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +16 -2
- package/dist/react.d.ts +16 -2
- package/dist/react.js +283 -48
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +283 -48
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +10 -0
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -796,11 +796,19 @@ var TEXTS = {
|
|
|
796
796
|
secondStepOff: "Off: signing in asks only for your password.",
|
|
797
797
|
turnOn: "Turn on",
|
|
798
798
|
turnOff: "Turn off",
|
|
799
|
-
addToApp: "
|
|
799
|
+
addToApp: "Scan this code with your authenticator app, or add the key below by hand, then enter the code it shows.",
|
|
800
800
|
openInApp: "Open in an authenticator app",
|
|
801
|
+
qrAlt: "QR code to add this account to an authenticator app",
|
|
801
802
|
recoveryCodes: "Recovery codes",
|
|
802
803
|
newRecoveryCodes: "New recovery codes",
|
|
803
804
|
keepCodes: "Keep these codes somewhere safe. Each works once, and they are not shown again.",
|
|
805
|
+
copyCodes: "Copy all",
|
|
806
|
+
downloadCodes: "Download .txt",
|
|
807
|
+
codesCopied: "The codes were copied.",
|
|
808
|
+
codesNotCopied: "The codes could not be copied. Select them and copy them by hand.",
|
|
809
|
+
change: "Change",
|
|
810
|
+
passwordSet: "Your account has a password.",
|
|
811
|
+
addAnotherPasskey: "Add a passkey",
|
|
804
812
|
passkeys: "Passkeys",
|
|
805
813
|
managePasskeys: "Add or remove a passkey",
|
|
806
814
|
passkeysHelp: "Sign in with your fingerprint, your face or your device's lock, without a password.",
|
|
@@ -980,11 +988,19 @@ var TEXTS = {
|
|
|
980
988
|
secondStepOff: "Inactivo: al entrar solo se pide tu contrase\xF1a.",
|
|
981
989
|
turnOn: "Activar",
|
|
982
990
|
turnOff: "Desactivar",
|
|
983
|
-
addToApp: "
|
|
991
|
+
addToApp: "Escanea este c\xF3digo con tu aplicaci\xF3n de autenticaci\xF3n, o agrega a mano la clave de abajo, y escribe el c\xF3digo que muestra.",
|
|
984
992
|
openInApp: "Abrir en una aplicaci\xF3n de autenticaci\xF3n",
|
|
993
|
+
qrAlt: "C\xF3digo QR para agregar esta cuenta a una aplicaci\xF3n de autenticaci\xF3n",
|
|
985
994
|
recoveryCodes: "C\xF3digos de recuperaci\xF3n",
|
|
986
995
|
newRecoveryCodes: "Nuevos c\xF3digos de recuperaci\xF3n",
|
|
987
996
|
keepCodes: "Guarda estos c\xF3digos en un lugar seguro. Cada uno sirve una vez y no se vuelven a mostrar.",
|
|
997
|
+
copyCodes: "Copiar todos",
|
|
998
|
+
downloadCodes: "Descargar .txt",
|
|
999
|
+
codesCopied: "Los c\xF3digos quedaron copiados.",
|
|
1000
|
+
codesNotCopied: "No se pudieron copiar los c\xF3digos. Selecci\xF3nalos y c\xF3pialos a mano.",
|
|
1001
|
+
change: "Cambiar",
|
|
1002
|
+
passwordSet: "Tu cuenta tiene contrase\xF1a.",
|
|
1003
|
+
addAnotherPasskey: "Agregar una llave de acceso",
|
|
988
1004
|
passkeys: "Llaves de acceso",
|
|
989
1005
|
managePasskeys: "Agregar o quitar una llave de acceso",
|
|
990
1006
|
passkeysHelp: "Entra con tu huella, tu rostro o el bloqueo de tu dispositivo, sin contrase\xF1a.",
|
|
@@ -2160,6 +2176,8 @@ function OrganizationMembers(props) {
|
|
|
2160
2176
|
const [role, setRole] = useState("");
|
|
2161
2177
|
const [name, setName] = useState("");
|
|
2162
2178
|
const [asking, setAsking] = useState(null);
|
|
2179
|
+
const [adding, setAdding] = useState(false);
|
|
2180
|
+
const [renamingOpen, setRenamingOpen] = useState(false);
|
|
2163
2181
|
const [gone, setGone] = useState(null);
|
|
2164
2182
|
const id = props.organizationId;
|
|
2165
2183
|
const when = props.formatDate ?? ((iso) => new Date(iso).toLocaleDateString());
|
|
@@ -2194,6 +2212,7 @@ function OrganizationMembers(props) {
|
|
|
2194
2212
|
const r = await run(() => auth.organizations.add(id, { email, role, locale: props.locale }), "add");
|
|
2195
2213
|
if (!r.ok) return;
|
|
2196
2214
|
setEmail("");
|
|
2215
|
+
setAdding(false);
|
|
2197
2216
|
setDone(f.t.memberAdded.replace("{email}", r.member.email));
|
|
2198
2217
|
saved({ kind: "member.added", organizationId: id, userId: r.member.userId, email: r.member.email, role: r.member.role || role });
|
|
2199
2218
|
await load();
|
|
@@ -2224,6 +2243,7 @@ function OrganizationMembers(props) {
|
|
|
2224
2243
|
if (!r.ok) return;
|
|
2225
2244
|
setSeat(r.organization);
|
|
2226
2245
|
setName(r.organization.name);
|
|
2246
|
+
setRenamingOpen(false);
|
|
2227
2247
|
setDone(f.t.organizationRenamed.replace("{name}", r.organization.name));
|
|
2228
2248
|
saved({ kind: "organization.renamed", organizationId: id, name: r.organization.name });
|
|
2229
2249
|
};
|
|
@@ -2253,6 +2273,24 @@ function OrganizationMembers(props) {
|
|
|
2253
2273
|
const archiving = seat.can.archive && !hidden("archive");
|
|
2254
2274
|
const deleting = seat.can.delete && !hidden("delete");
|
|
2255
2275
|
const renaming = seat.can.update && !hidden("rename");
|
|
2276
|
+
const alone = members !== null && members.every((m) => m.you);
|
|
2277
|
+
const addOpen = adding || alone;
|
|
2278
|
+
const open = (form) => {
|
|
2279
|
+
setDone(null);
|
|
2280
|
+
f.setError(null);
|
|
2281
|
+
if (form === "add") setAdding(true);
|
|
2282
|
+
else setRenamingOpen(true);
|
|
2283
|
+
};
|
|
2284
|
+
const cancelAdd = () => {
|
|
2285
|
+
setEmail("");
|
|
2286
|
+
f.setError(null);
|
|
2287
|
+
setAdding(false);
|
|
2288
|
+
};
|
|
2289
|
+
const cancelRename = () => {
|
|
2290
|
+
setName(seat.name);
|
|
2291
|
+
f.setError(null);
|
|
2292
|
+
setRenamingOpen(false);
|
|
2293
|
+
};
|
|
2256
2294
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "account", root, children: [
|
|
2257
2295
|
/* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "members", children: [
|
|
2258
2296
|
/* @__PURE__ */ jsxs(Heading, { f, children: [
|
|
@@ -2316,18 +2354,23 @@ function OrganizationMembers(props) {
|
|
|
2316
2354
|
}) }),
|
|
2317
2355
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2318
2356
|
] }),
|
|
2319
|
-
manage && giveable.length > 0 && /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "add-member", onSubmit: add, noValidate: true, children: [
|
|
2357
|
+
manage && giveable.length > 0 && (addOpen ? /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "add-member", onSubmit: add, noValidate: true, children: [
|
|
2320
2358
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.memberAdd }),
|
|
2321
2359
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "off", required: true, onChange: setEmail }),
|
|
2322
2360
|
/* @__PURE__ */ jsx(AddRole, { f, value: role, options: giveable.map((c) => ({ value: c.role, label: roleName(c) })), onChange: setRole }),
|
|
2323
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("add"), disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd })
|
|
2324
|
-
|
|
2361
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("add"), disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd }),
|
|
2362
|
+
!alone && /* @__PURE__ */ jsx(Cancel, { f, onClick: cancelAdd })
|
|
2363
|
+
] }) : /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "section", section: "add-member", children: /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => open("add"), children: f.t.memberAdd }) })),
|
|
2325
2364
|
(renaming || archiving || deleting) && /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "organization", children: [
|
|
2326
2365
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.organization }),
|
|
2327
|
-
renaming && /* @__PURE__ */ jsxs(Wrap, { f, as: "form", section: "rename", onSubmit: rename, noValidate: true, children: [
|
|
2366
|
+
renaming && (renamingOpen ? /* @__PURE__ */ jsxs(Wrap, { f, as: "form", section: "rename", onSubmit: rename, noValidate: true, children: [
|
|
2328
2367
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "organization", required: true, onChange: setName }),
|
|
2329
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("rename"), disabled: f.busy, className: f.cx("button"), children: f.t.organizationRename })
|
|
2330
|
-
|
|
2368
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("rename"), disabled: f.busy, className: f.cx("button"), children: f.t.organizationRename }),
|
|
2369
|
+
/* @__PURE__ */ jsx(Cancel, { f, onClick: cancelRename })
|
|
2370
|
+
] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2371
|
+
/* @__PURE__ */ jsx(Note, { f, children: seat.name }),
|
|
2372
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => open("rename"), children: f.t.organizationRename })
|
|
2373
|
+
] })),
|
|
2331
2374
|
asking === "archive" ? confirming(archiveQuestion, f.t.organizationArchive, () => void close("archive")) : asking === "delete" ? confirming(deleteQuestion, f.t.organizationDelete, () => void close("delete")) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2332
2375
|
archiving && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("archive"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("archive", f.t.organizationArchive, archiveQuestion, () => void close("archive")), children: f.t.organizationArchive }),
|
|
2333
2376
|
deleting && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("delete"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("delete", f.t.organizationDelete, deleteQuestion, () => void close("delete")), children: f.t.organizationDelete })
|
|
@@ -2346,6 +2389,7 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2346
2389
|
const [list, setList] = useState([]);
|
|
2347
2390
|
const [name, setName] = useState("");
|
|
2348
2391
|
const [password, setPassword] = useState("");
|
|
2392
|
+
const [adding, setAdding] = useState(false);
|
|
2349
2393
|
useEffect(() => {
|
|
2350
2394
|
void auth.methods().then((m) => {
|
|
2351
2395
|
const can2 = m.passkeyHere && canUsePasskeys();
|
|
@@ -2371,6 +2415,7 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2371
2415
|
setList([...list, r.passkey]);
|
|
2372
2416
|
setName("");
|
|
2373
2417
|
setPassword("");
|
|
2418
|
+
setAdding(false);
|
|
2374
2419
|
setDone(f.t.passkeyAdded);
|
|
2375
2420
|
props.onSaved?.({ kind: "passkey.added", id: r.passkey.id });
|
|
2376
2421
|
};
|
|
@@ -2380,43 +2425,123 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2380
2425
|
setList(list.filter((p) => p.id !== id));
|
|
2381
2426
|
props.onSaved?.({ kind: "passkey.removed", id });
|
|
2382
2427
|
};
|
|
2428
|
+
const cancel = () => {
|
|
2429
|
+
setName("");
|
|
2430
|
+
setPassword("");
|
|
2431
|
+
f.setError(null);
|
|
2432
|
+
setAdding(false);
|
|
2433
|
+
};
|
|
2434
|
+
const listed = list.length === 0 ? /* @__PURE__ */ jsx(Note, { f, children: f.t.noPasskeys }) : /* @__PURE__ */ jsx("ul", { className: f.cx("sessions"), children: list.map((p) => /* @__PURE__ */ jsxs("li", { className: f.cx("session"), children: [
|
|
2435
|
+
p.name || f.t.passkeyUnnamed,
|
|
2436
|
+
p.kind !== "unknown" && /* @__PURE__ */ jsx(Tag, { f, plain: ` \xB7 ${f.t.passkeyKinds[p.kind]}`, children: f.t.passkeyKinds[p.kind] }),
|
|
2437
|
+
" \xB7 ",
|
|
2438
|
+
when(p.createdAt),
|
|
2439
|
+
" ",
|
|
2440
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`remove:${p.id}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(p.id), children: f.t.removePasskey })
|
|
2441
|
+
] }, p.id)) });
|
|
2442
|
+
if (list.length > 0 && !adding) {
|
|
2443
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "passkeys", children: [
|
|
2444
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.passkeys }),
|
|
2445
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.passkeysHelp }),
|
|
2446
|
+
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2447
|
+
listed,
|
|
2448
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => {
|
|
2449
|
+
setDone(null);
|
|
2450
|
+
f.setError(null);
|
|
2451
|
+
setAdding(true);
|
|
2452
|
+
}, children: f.t.addAnotherPasskey }),
|
|
2453
|
+
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2454
|
+
] });
|
|
2455
|
+
}
|
|
2383
2456
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "passkeys", onSubmit: add, noValidate: true, children: [
|
|
2384
2457
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.passkeys }),
|
|
2385
2458
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.passkeysHelp }),
|
|
2386
2459
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2387
|
-
|
|
2388
|
-
p.name || f.t.passkeyUnnamed,
|
|
2389
|
-
p.kind !== "unknown" && /* @__PURE__ */ jsx(Tag, { f, plain: ` \xB7 ${f.t.passkeyKinds[p.kind]}`, children: f.t.passkeyKinds[p.kind] }),
|
|
2390
|
-
" \xB7 ",
|
|
2391
|
-
when(p.createdAt),
|
|
2392
|
-
" ",
|
|
2393
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`remove:${p.id}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(p.id), children: f.t.removePasskey })
|
|
2394
|
-
] }, p.id)) }),
|
|
2460
|
+
listed,
|
|
2395
2461
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.passkeyName, value: name, autoComplete: "off", onChange: setName }),
|
|
2396
2462
|
account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2397
2463
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.addPasskeyDevice }),
|
|
2398
2464
|
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("security_key"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void add(null, "security_key"), children: f.t.addSecurityKey }),
|
|
2465
|
+
list.length > 0 && /* @__PURE__ */ jsx(Cancel, { f, onClick: cancel }),
|
|
2399
2466
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2400
2467
|
] });
|
|
2401
2468
|
}
|
|
2469
|
+
function Cancel({ f, onClick }) {
|
|
2470
|
+
return /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick, children: f.t.cancel });
|
|
2471
|
+
}
|
|
2472
|
+
function RecoveryCodes({ f, codes }) {
|
|
2473
|
+
const [copied, setCopied] = useState(null);
|
|
2474
|
+
useEffect(() => setCopied(null), [codes]);
|
|
2475
|
+
const copy = async () => {
|
|
2476
|
+
try {
|
|
2477
|
+
await navigator.clipboard.writeText(codes.join("\n"));
|
|
2478
|
+
setCopied(true);
|
|
2479
|
+
} catch {
|
|
2480
|
+
setCopied(false);
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2483
|
+
const download = () => {
|
|
2484
|
+
const file = new Blob([`${f.t.recoveryCodes}
|
|
2485
|
+
|
|
2486
|
+
${codes.join("\n")}
|
|
2487
|
+
`], { type: "text/plain;charset=utf-8" });
|
|
2488
|
+
const url = URL.createObjectURL(file);
|
|
2489
|
+
const a = document.createElement("a");
|
|
2490
|
+
a.href = url;
|
|
2491
|
+
a.download = "recovery-codes.txt";
|
|
2492
|
+
document.body.appendChild(a);
|
|
2493
|
+
a.click();
|
|
2494
|
+
a.remove();
|
|
2495
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
2496
|
+
};
|
|
2497
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2498
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.keepCodes }),
|
|
2499
|
+
/* @__PURE__ */ jsx("ul", { className: f.cx("codes"), children: codes.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: c }) }, c)) }),
|
|
2500
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", className: f.cx("providerButton"), onClick: () => void copy(), children: f.t.copyCodes }),
|
|
2501
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", className: f.cx("providerButton"), onClick: download, children: f.t.downloadCodes }),
|
|
2502
|
+
copied === true && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: f.t.codesCopied }),
|
|
2503
|
+
copied === false && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.t.codesNotCopied })
|
|
2504
|
+
] });
|
|
2505
|
+
}
|
|
2402
2506
|
function ProfilePart({ props, account, onSaved }) {
|
|
2403
2507
|
const auth = useAuth();
|
|
2404
2508
|
const { f, done, setDone, run, general } = useSection(props);
|
|
2405
2509
|
const [name, setName] = useState(account.name);
|
|
2510
|
+
const [editing, setEditing] = useState(account.name.trim() === "");
|
|
2406
2511
|
const submit = async (e) => {
|
|
2407
2512
|
e.preventDefault();
|
|
2408
2513
|
const r = await run(() => auth.account.update({ name }));
|
|
2409
2514
|
if (!r.ok) return;
|
|
2410
2515
|
onSaved(r.account);
|
|
2516
|
+
setName(r.account.name);
|
|
2517
|
+
setEditing(r.account.name.trim() === "");
|
|
2411
2518
|
setDone(f.t.saved);
|
|
2412
2519
|
props.onSaved?.({ kind: "profile.saved", name: r.account.name });
|
|
2413
2520
|
};
|
|
2521
|
+
const cancel = () => {
|
|
2522
|
+
setName(account.name);
|
|
2523
|
+
f.setError(null);
|
|
2524
|
+
setEditing(false);
|
|
2525
|
+
};
|
|
2526
|
+
if (!editing) {
|
|
2527
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "profile", children: [
|
|
2528
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.profile }),
|
|
2529
|
+
/* @__PURE__ */ jsx(Note, { f, children: account.name }),
|
|
2530
|
+
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
2531
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => {
|
|
2532
|
+
setDone(null);
|
|
2533
|
+
setEditing(true);
|
|
2534
|
+
}, children: f.t.change }),
|
|
2535
|
+
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2536
|
+
] });
|
|
2537
|
+
}
|
|
2414
2538
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "profile", onSubmit: submit, noValidate: true, children: [
|
|
2415
2539
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.profile }),
|
|
2416
2540
|
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
2417
2541
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2418
2542
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "name", onChange: setName }),
|
|
2419
2543
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.save }),
|
|
2544
|
+
account.name.trim() !== "" && /* @__PURE__ */ jsx(Cancel, { f, onClick: cancel }),
|
|
2420
2545
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2421
2546
|
] });
|
|
2422
2547
|
}
|
|
@@ -2425,15 +2550,35 @@ function EmailPart({ props, account }) {
|
|
|
2425
2550
|
const { f, done, setDone, run, general } = useSection(props);
|
|
2426
2551
|
const [email, setEmail] = useState("");
|
|
2427
2552
|
const [password, setPassword] = useState("");
|
|
2553
|
+
const [editing, setEditing] = useState(false);
|
|
2428
2554
|
const submit = async (e) => {
|
|
2429
2555
|
e.preventDefault();
|
|
2430
2556
|
if (!f.check(checkEmail(email), account.hasPassword && checkPassword(password))) return;
|
|
2431
2557
|
const r = await run(() => auth.account.changeEmail({ email, password }));
|
|
2432
2558
|
if (!r.ok) return;
|
|
2559
|
+
setEmail("");
|
|
2433
2560
|
setPassword("");
|
|
2561
|
+
setEditing(false);
|
|
2434
2562
|
setDone(f.t.emailSent.replace("{email}", r.email));
|
|
2435
2563
|
props.onSaved?.({ kind: "email.change_requested", email: r.email });
|
|
2436
2564
|
};
|
|
2565
|
+
const cancel = () => {
|
|
2566
|
+
setEmail("");
|
|
2567
|
+
setPassword("");
|
|
2568
|
+
f.setError(null);
|
|
2569
|
+
setEditing(false);
|
|
2570
|
+
};
|
|
2571
|
+
if (!editing) {
|
|
2572
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "email", children: [
|
|
2573
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.emailAddress }),
|
|
2574
|
+
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
2575
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => {
|
|
2576
|
+
setDone(null);
|
|
2577
|
+
setEditing(true);
|
|
2578
|
+
}, children: f.t.changeEmail }),
|
|
2579
|
+
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2580
|
+
] });
|
|
2581
|
+
}
|
|
2437
2582
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "email", onSubmit: submit, noValidate: true, children: [
|
|
2438
2583
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.emailAddress }),
|
|
2439
2584
|
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
@@ -2441,7 +2586,7 @@ function EmailPart({ props, account }) {
|
|
|
2441
2586
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.newEmail, value: email, autoComplete: "email", required: true, onChange: setEmail }),
|
|
2442
2587
|
account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2443
2588
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.changeEmail }),
|
|
2444
|
-
|
|
2589
|
+
/* @__PURE__ */ jsx(Cancel, { f, onClick: cancel })
|
|
2445
2590
|
] });
|
|
2446
2591
|
}
|
|
2447
2592
|
function LinkedPart({ props }) {
|
|
@@ -2506,6 +2651,7 @@ function PasswordPart({ props }) {
|
|
|
2506
2651
|
const { f, done, setDone, run, general } = useSection(props);
|
|
2507
2652
|
const [password, setPassword] = useState("");
|
|
2508
2653
|
const [newPassword, setNewPassword] = useState("");
|
|
2654
|
+
const [editing, setEditing] = useState(false);
|
|
2509
2655
|
usePasswordPolicy(f, useMethods(auth));
|
|
2510
2656
|
const submit = async (e) => {
|
|
2511
2657
|
e.preventDefault();
|
|
@@ -2514,16 +2660,34 @@ function PasswordPart({ props }) {
|
|
|
2514
2660
|
if (!r.ok) return;
|
|
2515
2661
|
setPassword("");
|
|
2516
2662
|
setNewPassword("");
|
|
2663
|
+
setEditing(false);
|
|
2517
2664
|
setDone(f.t.passwordChangedHere);
|
|
2518
2665
|
props.onSaved?.({ kind: "password.changed" });
|
|
2519
2666
|
};
|
|
2667
|
+
const cancel = () => {
|
|
2668
|
+
setPassword("");
|
|
2669
|
+
setNewPassword("");
|
|
2670
|
+
f.setError(null);
|
|
2671
|
+
setEditing(false);
|
|
2672
|
+
};
|
|
2673
|
+
if (!editing) {
|
|
2674
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "password", children: [
|
|
2675
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.password }),
|
|
2676
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.passwordSet }),
|
|
2677
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => {
|
|
2678
|
+
setDone(null);
|
|
2679
|
+
setEditing(true);
|
|
2680
|
+
}, children: f.t.changePassword }),
|
|
2681
|
+
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2682
|
+
] });
|
|
2683
|
+
}
|
|
2520
2684
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "password", onSubmit: submit, noValidate: true, children: [
|
|
2521
|
-
/* @__PURE__ */ jsx(Heading, { f, children: f.t.
|
|
2685
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.password }),
|
|
2522
2686
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2523
2687
|
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2524
2688
|
/* @__PURE__ */ jsx(Field, { f, name: "newPassword", type: "password", label: f.t.newPassword, value: newPassword, autoComplete: "new-password", required: true, onChange: setNewPassword, hint: f.passwordRule }),
|
|
2525
2689
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.changePassword }),
|
|
2526
|
-
|
|
2690
|
+
/* @__PURE__ */ jsx(Cancel, { f, onClick: cancel })
|
|
2527
2691
|
] });
|
|
2528
2692
|
}
|
|
2529
2693
|
function SecondStepPart({ props, account, onChanged }) {
|
|
@@ -2533,10 +2697,11 @@ function SecondStepPart({ props, account, onChanged }) {
|
|
|
2533
2697
|
const [code, setCode] = useState("");
|
|
2534
2698
|
const [setup, setSetup] = useState(null);
|
|
2535
2699
|
const [codes, setCodes] = useState(null);
|
|
2700
|
+
const [asking, setAsking] = useState(null);
|
|
2536
2701
|
const start = async (e) => {
|
|
2537
2702
|
e.preventDefault();
|
|
2538
2703
|
const r = await run(() => auth.account.mfa.setup({ password }));
|
|
2539
|
-
if (r.ok) setSetup({ secret: r.secret, otpauthUri: r.otpauthUri });
|
|
2704
|
+
if (r.ok) setSetup({ secret: r.secret, otpauthUri: r.otpauthUri, qr: r.qr ?? "" });
|
|
2540
2705
|
};
|
|
2541
2706
|
const confirm = async (e) => {
|
|
2542
2707
|
e.preventDefault();
|
|
@@ -2549,30 +2714,41 @@ function SecondStepPart({ props, account, onChanged }) {
|
|
|
2549
2714
|
onChanged(true);
|
|
2550
2715
|
props.onSaved?.({ kind: "mfa.enabled" });
|
|
2551
2716
|
};
|
|
2552
|
-
const turnOff = async (
|
|
2553
|
-
|
|
2554
|
-
const r = await run(() => auth.account.mfa.disable({ password }));
|
|
2717
|
+
const turnOff = async (key) => {
|
|
2718
|
+
const r = await run(() => auth.account.mfa.disable({ password }), key);
|
|
2555
2719
|
if (!r.ok) return;
|
|
2556
2720
|
setPassword("");
|
|
2721
|
+
setAsking(null);
|
|
2557
2722
|
setCodes(null);
|
|
2558
2723
|
onChanged(false);
|
|
2559
2724
|
props.onSaved?.({ kind: "mfa.disabled" });
|
|
2560
2725
|
};
|
|
2561
|
-
const renew = async () => {
|
|
2562
|
-
const r = await run(() => auth.account.mfa.recoveryCodes({ password }),
|
|
2726
|
+
const renew = async (key) => {
|
|
2727
|
+
const r = await run(() => auth.account.mfa.recoveryCodes({ password }), key);
|
|
2563
2728
|
if (!r.ok) return;
|
|
2729
|
+
setPassword("");
|
|
2730
|
+
setAsking(null);
|
|
2564
2731
|
setCodes(r.recoveryCodes);
|
|
2565
2732
|
props.onSaved?.({ kind: "recovery_codes.regenerated" });
|
|
2566
2733
|
};
|
|
2734
|
+
const press = (what) => {
|
|
2735
|
+
f.setError(null);
|
|
2736
|
+
if (!account.hasPassword) return void (what === "off" ? turnOff(what) : renew(what));
|
|
2737
|
+
setPassword("");
|
|
2738
|
+
setCodes(null);
|
|
2739
|
+
setAsking(what);
|
|
2740
|
+
};
|
|
2741
|
+
const cancel = () => {
|
|
2742
|
+
setPassword("");
|
|
2743
|
+
f.setError(null);
|
|
2744
|
+
setAsking(null);
|
|
2745
|
+
};
|
|
2567
2746
|
const passwordField = account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword });
|
|
2568
|
-
const shown = codes && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2569
|
-
/* @__PURE__ */ jsx(Note, { f, children: f.t.keepCodes }),
|
|
2570
|
-
/* @__PURE__ */ jsx("ul", { className: f.cx("codes"), children: codes.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: c }) }, c)) })
|
|
2571
|
-
] });
|
|
2572
2747
|
if (setup) {
|
|
2573
2748
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "secondStep", onSubmit: confirm, noValidate: true, children: [
|
|
2574
2749
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2575
2750
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.addToApp }),
|
|
2751
|
+
setup.qr && /* @__PURE__ */ jsx("img", { className: f.cx("qr"), src: setup.qr, width: 220, height: 220, alt: f.t.qrAlt }),
|
|
2576
2752
|
/* @__PURE__ */ jsx("code", { className: f.cx("secret"), children: setup.secret }),
|
|
2577
2753
|
/* @__PURE__ */ jsx(A, { f, href: setup.otpauthUri, children: f.t.openInApp }),
|
|
2578
2754
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
@@ -2580,14 +2756,36 @@ function SecondStepPart({ props, account, onChanged }) {
|
|
|
2580
2756
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2581
2757
|
] });
|
|
2582
2758
|
}
|
|
2583
|
-
|
|
2759
|
+
if (!account.mfaEnabled) {
|
|
2760
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "secondStep", onSubmit: start, noValidate: true, children: [
|
|
2761
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2762
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.secondStepOff }),
|
|
2763
|
+
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2764
|
+
passwordField,
|
|
2765
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.turnOn })
|
|
2766
|
+
] });
|
|
2767
|
+
}
|
|
2768
|
+
if (asking) {
|
|
2769
|
+
const submit = (e) => {
|
|
2770
|
+
e.preventDefault();
|
|
2771
|
+
void (asking === "off" ? turnOff(SUBMIT) : renew(SUBMIT));
|
|
2772
|
+
};
|
|
2773
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "secondStep", onSubmit: submit, noValidate: true, children: [
|
|
2774
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2775
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.secondStepOn }),
|
|
2776
|
+
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2777
|
+
passwordField,
|
|
2778
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: asking === "off" ? "danger" : "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: asking === "off" ? f.t.turnOff : f.t.newRecoveryCodes }),
|
|
2779
|
+
/* @__PURE__ */ jsx(Cancel, { f, onClick: cancel })
|
|
2780
|
+
] });
|
|
2781
|
+
}
|
|
2782
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "secondStep", children: [
|
|
2584
2783
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2585
|
-
/* @__PURE__ */ jsx(Note, { f, children:
|
|
2586
|
-
|
|
2784
|
+
/* @__PURE__ */ jsx(Note, { f, children: f.t.secondStepOn }),
|
|
2785
|
+
codes && /* @__PURE__ */ jsx(RecoveryCodes, { f, codes }),
|
|
2587
2786
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2588
|
-
|
|
2589
|
-
/* @__PURE__ */ jsx(f.Button, { type: "
|
|
2590
|
-
account.mfaEnabled && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("codes"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void renew(), children: f.t.newRecoveryCodes })
|
|
2787
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("off"), disabled: f.busy, className: f.cx("button"), onClick: () => press("off"), children: f.t.turnOff }),
|
|
2788
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("codes"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => press("codes"), children: f.t.newRecoveryCodes })
|
|
2591
2789
|
] });
|
|
2592
2790
|
}
|
|
2593
2791
|
function PhonePart({ props, account, onChanged }) {
|
|
@@ -2600,6 +2798,7 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2600
2798
|
const [code, setCode] = useState("");
|
|
2601
2799
|
const [sentTo, setSentTo] = useState("");
|
|
2602
2800
|
const [codes, setCodes] = useState(null);
|
|
2801
|
+
const [removing, setRemoving] = useState(false);
|
|
2603
2802
|
const load = () => auth.account.mfa.factors().then((w) => {
|
|
2604
2803
|
setWays(w);
|
|
2605
2804
|
if (w && w.phoneChannels.length > 0 && !w.phoneChannels.includes(channel)) setChannel(w.phoneChannels[0]);
|
|
@@ -2620,21 +2819,34 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2620
2819
|
setSentTo("");
|
|
2621
2820
|
setCode("");
|
|
2622
2821
|
setPassword("");
|
|
2822
|
+
setNumber("");
|
|
2623
2823
|
if (r.recoveryCodes.length > 0) setCodes(r.recoveryCodes);
|
|
2624
2824
|
onChanged(true);
|
|
2625
2825
|
props.onSaved?.({ kind: "phone.added", channel });
|
|
2626
2826
|
await load();
|
|
2627
2827
|
};
|
|
2628
|
-
const remove = async (
|
|
2629
|
-
|
|
2630
|
-
const r = await run(() => auth.account.mfa.removePhone({ password }));
|
|
2828
|
+
const remove = async (key) => {
|
|
2829
|
+
const r = await run(() => auth.account.mfa.removePhone({ password }), key);
|
|
2631
2830
|
if (!r.ok) return;
|
|
2632
2831
|
setPassword("");
|
|
2832
|
+
setRemoving(false);
|
|
2833
|
+
setCodes(null);
|
|
2633
2834
|
await load();
|
|
2634
2835
|
const left = await auth.account.mfa.factors();
|
|
2635
2836
|
onChanged(Boolean(left?.totp));
|
|
2636
2837
|
props.onSaved?.({ kind: "phone.removed" });
|
|
2637
2838
|
};
|
|
2839
|
+
const press = () => {
|
|
2840
|
+
f.setError(null);
|
|
2841
|
+
if (!account.hasPassword) return void remove("remove");
|
|
2842
|
+
setPassword("");
|
|
2843
|
+
setRemoving(true);
|
|
2844
|
+
};
|
|
2845
|
+
const cancel = () => {
|
|
2846
|
+
setPassword("");
|
|
2847
|
+
f.setError(null);
|
|
2848
|
+
setRemoving(false);
|
|
2849
|
+
};
|
|
2638
2850
|
const passwordField = account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword });
|
|
2639
2851
|
if (sentTo) {
|
|
2640
2852
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "phone", onSubmit: confirm, noValidate: true, children: [
|
|
@@ -2645,23 +2857,46 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2645
2857
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2646
2858
|
] });
|
|
2647
2859
|
}
|
|
2648
|
-
|
|
2860
|
+
if (ways.phone) {
|
|
2861
|
+
const by = ways.phone.channel === "whatsapp" ? f.t.byWhatsapp : ways.phone.channel === "sms" ? f.t.bySms : "";
|
|
2862
|
+
const on = /* @__PURE__ */ jsxs(Note, { f, children: [
|
|
2863
|
+
f.t.phoneOn.replace("{to}", ways.phone.number),
|
|
2864
|
+
by && /* @__PURE__ */ jsx(Tag, { f, plain: ` \xB7 ${by}`, children: by })
|
|
2865
|
+
] });
|
|
2866
|
+
if (removing) {
|
|
2867
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "phone", onSubmit: (e) => {
|
|
2868
|
+
e.preventDefault();
|
|
2869
|
+
void remove(SUBMIT);
|
|
2870
|
+
}, noValidate: true, children: [
|
|
2871
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.phone }),
|
|
2872
|
+
on,
|
|
2873
|
+
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2874
|
+
passwordField,
|
|
2875
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "danger", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.removePhone }),
|
|
2876
|
+
/* @__PURE__ */ jsx(Cancel, { f, onClick: cancel })
|
|
2877
|
+
] });
|
|
2878
|
+
}
|
|
2879
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "section", section: "phone", children: [
|
|
2880
|
+
/* @__PURE__ */ jsx(Heading, { f, children: f.t.phone }),
|
|
2881
|
+
on,
|
|
2882
|
+
codes && /* @__PURE__ */ jsx(RecoveryCodes, { f, codes }),
|
|
2883
|
+
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2884
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("remove"), disabled: f.busy, className: f.cx("button"), onClick: press, children: f.t.removePhone })
|
|
2885
|
+
] });
|
|
2886
|
+
}
|
|
2887
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "phone", onSubmit: add, noValidate: true, children: [
|
|
2649
2888
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.phone }),
|
|
2650
|
-
/* @__PURE__ */ jsx(Note, { f, children:
|
|
2651
|
-
codes && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2652
|
-
/* @__PURE__ */ jsx(Note, { f, children: f.t.keepCodes }),
|
|
2653
|
-
/* @__PURE__ */ jsx("ul", { className: f.cx("codes"), children: codes.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: c }) }, c)) })
|
|
2654
|
-
] }),
|
|
2889
|
+
/* @__PURE__ */ jsx(Note, { f, children: `${f.t.phoneOff} ${f.t.phoneHelp}` }),
|
|
2655
2890
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2891
|
+
/* @__PURE__ */ jsx(Field, { f, name: "phone", type: "tel", label: f.t.phone, value: number, autoComplete: "tel", required: true, onChange: setNumber }),
|
|
2892
|
+
ways.phoneChannels.length > 1 && f.C.Select && /* @__PURE__ */ jsx(ChannelPick, { f, value: channel, channels: ways.phoneChannels, onChange: setChannel }),
|
|
2893
|
+
ways.phoneChannels.length > 1 && !f.C.Select && /* @__PURE__ */ jsx("div", { className: f.cx("field"), role: "radiogroup", children: ways.phoneChannels.map((c) => /* @__PURE__ */ jsxs("label", { className: f.cx("label"), children: [
|
|
2659
2894
|
/* @__PURE__ */ jsx("input", { type: "radio", name: "channel", value: c, checked: channel === c, disabled: f.busy, onChange: () => setChannel(c) }),
|
|
2660
2895
|
" ",
|
|
2661
2896
|
c === "whatsapp" ? f.t.byWhatsapp : f.t.bySms
|
|
2662
2897
|
] }, c)) }),
|
|
2663
2898
|
passwordField,
|
|
2664
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant:
|
|
2899
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.addPhone })
|
|
2665
2900
|
] });
|
|
2666
2901
|
}
|
|
2667
2902
|
function AgentsPart({ props, when }) {
|