@elvix.is/sdk 0.5.3 → 0.5.5
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/dist/react.d.ts +92 -36
- package/dist/react.js +1027 -314
- package/package.json +2 -2
package/dist/react.js
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/react/size.ts
|
|
3
|
+
function sizeStyle(p) {
|
|
4
|
+
const s = {};
|
|
5
|
+
if (p.width !== void 0) s.width = p.width;
|
|
6
|
+
if (p.height !== void 0) s.height = p.height;
|
|
7
|
+
if (p.minWidth !== void 0) s.minWidth = p.minWidth;
|
|
8
|
+
if (p.maxWidth !== void 0) s.maxWidth = p.maxWidth;
|
|
9
|
+
if (p.minHeight !== void 0) s.minHeight = p.minHeight;
|
|
10
|
+
if (p.maxHeight !== void 0) s.maxHeight = p.maxHeight;
|
|
11
|
+
return s;
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
// src/react/elvix-card.tsx
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
16
|
function ElvixCard({
|
|
3
17
|
title,
|
|
4
18
|
footer,
|
|
5
19
|
className = "",
|
|
6
|
-
|
|
20
|
+
style,
|
|
21
|
+
children,
|
|
22
|
+
width,
|
|
23
|
+
height,
|
|
24
|
+
minWidth,
|
|
25
|
+
maxWidth,
|
|
26
|
+
minHeight,
|
|
27
|
+
maxHeight
|
|
7
28
|
}) {
|
|
8
|
-
|
|
29
|
+
const sized = sizeStyle({ width, height, minWidth, maxWidth, minHeight, maxHeight });
|
|
30
|
+
return /* @__PURE__ */ jsxs(
|
|
9
31
|
"div",
|
|
10
32
|
{
|
|
11
33
|
className: `elvix-card ${className}`.trim(),
|
|
@@ -17,35 +39,39 @@ function ElvixCard({
|
|
|
17
39
|
display: "flex",
|
|
18
40
|
flexDirection: "column",
|
|
19
41
|
maxWidth: "440px",
|
|
20
|
-
width: "100%"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
title && /* @__PURE__ */ React.createElement(
|
|
24
|
-
"div",
|
|
25
|
-
{
|
|
26
|
-
style: {
|
|
27
|
-
padding: "20px 24px 0",
|
|
28
|
-
fontSize: "16px",
|
|
29
|
-
fontWeight: 600,
|
|
30
|
-
color: "var(--elvix-primary-strong, #5d4dff)"
|
|
31
|
-
}
|
|
42
|
+
width: "100%",
|
|
43
|
+
...style,
|
|
44
|
+
...sized
|
|
32
45
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
children: [
|
|
47
|
+
title && /* @__PURE__ */ jsx(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
style: {
|
|
51
|
+
padding: "20px 24px 0",
|
|
52
|
+
fontSize: "16px",
|
|
53
|
+
fontWeight: 600,
|
|
54
|
+
color: "var(--elvix-primary-strong, #5d4dff)"
|
|
55
|
+
},
|
|
56
|
+
children: title
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "16px 24px", flex: 1 }, children }),
|
|
60
|
+
footer && /* @__PURE__ */ jsx(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
style: {
|
|
64
|
+
padding: "12px 24px",
|
|
65
|
+
borderTop: "1px solid var(--elvix-primary-12, rgba(93,77,255,0.12))",
|
|
66
|
+
background: "rgba(0,0,0,0.02)",
|
|
67
|
+
fontSize: "12px",
|
|
68
|
+
color: "rgba(0,0,0,0.55)"
|
|
69
|
+
},
|
|
70
|
+
children: footer
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
}
|
|
49
75
|
);
|
|
50
76
|
}
|
|
51
77
|
|
|
@@ -57,6 +83,7 @@ import {
|
|
|
57
83
|
useMemo,
|
|
58
84
|
useState
|
|
59
85
|
} from "react";
|
|
86
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
60
87
|
var ELVIX_DEFAULT_BRAND = {
|
|
61
88
|
light: { primary: "#5d4dff", on: "#ffffff" },
|
|
62
89
|
dark: { primary: "#8e7dff", on: "#0a0a0b" }
|
|
@@ -140,15 +167,15 @@ function ElvixProvider({
|
|
|
140
167
|
appError,
|
|
141
168
|
resolvedTheme: effectiveTheme
|
|
142
169
|
};
|
|
143
|
-
return /* @__PURE__ */
|
|
170
|
+
return /* @__PURE__ */ jsx2(ElvixContext.Provider, { value, children: /* @__PURE__ */ jsx2(
|
|
144
171
|
"div",
|
|
145
172
|
{
|
|
146
173
|
"data-elvix-theme": effectiveTheme,
|
|
147
174
|
style: cssVars,
|
|
148
|
-
className: (effectiveTheme === "dark" ? "dark " : "") + "elvix-sdk-root " + className
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
));
|
|
175
|
+
className: (effectiveTheme === "dark" ? "dark " : "") + "elvix-sdk-root " + className,
|
|
176
|
+
children
|
|
177
|
+
}
|
|
178
|
+
) });
|
|
152
179
|
}
|
|
153
180
|
function appBrand(app) {
|
|
154
181
|
if (!app?.brandColor) return null;
|
|
@@ -246,12 +273,20 @@ function isSameOrigin(baseUrl) {
|
|
|
246
273
|
}
|
|
247
274
|
|
|
248
275
|
// src/react/elvix-sign-in.tsx
|
|
276
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
249
277
|
function ElvixSignIn({
|
|
250
278
|
onResult,
|
|
251
279
|
redirectAfterSignIn,
|
|
252
280
|
copy: copyProp,
|
|
253
|
-
className = ""
|
|
281
|
+
className = "",
|
|
282
|
+
width,
|
|
283
|
+
height,
|
|
284
|
+
minWidth,
|
|
285
|
+
maxWidth,
|
|
286
|
+
minHeight,
|
|
287
|
+
maxHeight
|
|
254
288
|
}) {
|
|
289
|
+
const sized = sizeStyle({ width, height, minWidth, maxWidth, minHeight, maxHeight });
|
|
255
290
|
const ctx = useElvixContext();
|
|
256
291
|
const app = useElvixApp();
|
|
257
292
|
const copy = resolveCopy(app?.strings, copyProp);
|
|
@@ -336,67 +371,549 @@ function ElvixSignIn({
|
|
|
336
371
|
}
|
|
337
372
|
const card = `elvix-card ${className}`.trim();
|
|
338
373
|
if (step === "done") {
|
|
339
|
-
return /* @__PURE__ */
|
|
374
|
+
return /* @__PURE__ */ jsx3("div", { className: card, style: sized, "data-elvix-pane": "done", children: /* @__PURE__ */ jsx3("p", { children: copy.signedInText }) });
|
|
340
375
|
}
|
|
341
|
-
return /* @__PURE__ */
|
|
342
|
-
"
|
|
343
|
-
{
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
376
|
+
return /* @__PURE__ */ jsxs2("div", { className: card, style: sized, "data-elvix-pane": step, children: [
|
|
377
|
+
/* @__PURE__ */ jsx3("h2", { className: "elvix-h", children: title }),
|
|
378
|
+
copy.subtitle && /* @__PURE__ */ jsx3("p", { className: "elvix-muted elvix-subtitle", children: copy.subtitle }),
|
|
379
|
+
step === "identify" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
380
|
+
app?.methodGoogle && /* @__PURE__ */ jsx3(
|
|
381
|
+
"button",
|
|
382
|
+
{
|
|
383
|
+
type: "button",
|
|
384
|
+
onClick: startGoogle,
|
|
385
|
+
disabled: busy,
|
|
386
|
+
className: "elvix-btn elvix-btn-google",
|
|
387
|
+
"data-elvix-method": "google",
|
|
388
|
+
children: copy.googleButton
|
|
389
|
+
}
|
|
390
|
+
),
|
|
391
|
+
app?.methodEmailOtp && /* @__PURE__ */ jsxs2("form", { onSubmit: startOtp, "data-elvix-method": "email_otp", className: "elvix-otp-form", children: [
|
|
392
|
+
/* @__PURE__ */ jsx3(
|
|
393
|
+
"input",
|
|
394
|
+
{
|
|
395
|
+
type: "email",
|
|
396
|
+
value: email,
|
|
397
|
+
onChange: (ev) => setEmail(ev.target.value),
|
|
398
|
+
placeholder: copy.emailPlaceholder,
|
|
399
|
+
required: true,
|
|
400
|
+
disabled: busy,
|
|
401
|
+
className: "elvix-input"
|
|
402
|
+
}
|
|
403
|
+
),
|
|
404
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? copy.sendingLabel : copy.sendCodeButton })
|
|
405
|
+
] })
|
|
406
|
+
] }),
|
|
407
|
+
step === "code" && /* @__PURE__ */ jsxs2("form", { onSubmit: verifyOtp, className: "elvix-otp-form", children: [
|
|
408
|
+
/* @__PURE__ */ jsx3("p", { className: "elvix-muted", children: fillCopy(copy.codeSentSubtitle ?? "", { email }) }),
|
|
409
|
+
/* @__PURE__ */ jsx3(
|
|
410
|
+
"input",
|
|
411
|
+
{
|
|
412
|
+
type: "text",
|
|
413
|
+
inputMode: "numeric",
|
|
414
|
+
pattern: "[0-9]*",
|
|
415
|
+
maxLength: 6,
|
|
416
|
+
value: code,
|
|
417
|
+
onChange: (ev) => setCode(ev.target.value.replace(/\D/g, "")),
|
|
418
|
+
placeholder: copy.codePlaceholder,
|
|
419
|
+
required: true,
|
|
420
|
+
disabled: busy,
|
|
421
|
+
className: "elvix-input"
|
|
422
|
+
}
|
|
423
|
+
),
|
|
424
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? copy.verifyingLabel : submitLabel })
|
|
425
|
+
] }),
|
|
426
|
+
error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "elvix-error", children: error })
|
|
427
|
+
] });
|
|
377
428
|
}
|
|
378
429
|
|
|
379
|
-
// src/react/elvix-sign-in-
|
|
380
|
-
import { useState as useState3 } from "react";
|
|
430
|
+
// src/react/elvix-sign-in-form.tsx
|
|
431
|
+
import { useMemo as useMemo2, useState as useState3 } from "react";
|
|
381
432
|
|
|
382
433
|
// src/react/elvix-shield.tsx
|
|
434
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
383
435
|
function ElvixShield({
|
|
384
436
|
size,
|
|
385
437
|
fill,
|
|
386
438
|
accent
|
|
387
439
|
}) {
|
|
388
|
-
return /* @__PURE__ */
|
|
389
|
-
|
|
440
|
+
return /* @__PURE__ */ jsxs3("svg", { width: size, height: size, viewBox: "2 2 20 20", "aria-hidden": true, style: { display: "block" }, children: [
|
|
441
|
+
/* @__PURE__ */ jsx4(
|
|
442
|
+
"path",
|
|
443
|
+
{
|
|
444
|
+
fill,
|
|
445
|
+
fillRule: "evenodd",
|
|
446
|
+
d: "M 6 2.5 C 4.34 2.5 3 3.84 3 5.5 L 3 12.5 C 3 17.5 7 20.7 12 22 C 17 20.7 21 17.5 21 12.5 L 21 5.5 C 21 3.84 19.66 2.5 18 2.5 L 6 2.5 Z M 12 8.4 C 9.79 8.4 8 10.19 8 12.4 C 8 14.61 9.79 16.4 12 16.4 C 13.21 16.4 14.3 15.86 15.04 15 L 13.6 13.77 C 13.21 14.23 12.64 14.5 12 14.5 C 11.04 14.5 10.21 13.86 9.91 13 L 15.95 13 C 15.98 12.8 16 12.6 16 12.4 C 16 10.19 14.21 8.4 12 8.4 Z M 9.91 11.8 L 14.09 11.8 C 13.79 10.94 12.96 10.3 12 10.3 C 11.04 10.3 10.21 10.94 9.91 11.8 Z"
|
|
447
|
+
}
|
|
448
|
+
),
|
|
449
|
+
/* @__PURE__ */ jsx4("circle", { cx: "19.5", cy: "4.5", r: "2.4", fill: accent })
|
|
450
|
+
] });
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// src/react/elvix-secured-badge.tsx
|
|
454
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
455
|
+
var ELVIX_URL = "https://elvix.is";
|
|
456
|
+
var SIZE = {
|
|
457
|
+
sm: { height: 28, padX: 10, font: 11.5, icon: 14, gap: 6 },
|
|
458
|
+
md: { height: 32, padX: 12, font: 12.5, icon: 16, gap: 7 },
|
|
459
|
+
lg: { height: 36, padX: 14, font: 13, icon: 18, gap: 8 }
|
|
460
|
+
};
|
|
461
|
+
var TONE = {
|
|
462
|
+
white: {
|
|
463
|
+
light: { bg: "#ffffff", border: "#e4e4e7", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" },
|
|
464
|
+
dark: { bg: "#ffffff", border: "transparent", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" }
|
|
465
|
+
},
|
|
466
|
+
dark: {
|
|
467
|
+
light: { bg: "#0a0a0b", border: "rgba(0,0,0,0.1)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" },
|
|
468
|
+
dark: { bg: "#0a0a0b", border: "rgba(255,255,255,0.1)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" }
|
|
469
|
+
},
|
|
470
|
+
outline: {
|
|
471
|
+
light: { bg: "transparent", border: "rgba(0,0,0,0.15)", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" },
|
|
472
|
+
dark: { bg: "transparent", border: "rgba(142,125,255,0.4)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" }
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
function ElvixSecuredBadge({
|
|
476
|
+
variant = "white",
|
|
477
|
+
size = "md",
|
|
478
|
+
theme = "dark",
|
|
479
|
+
accentColor = "#8e7dff",
|
|
480
|
+
href = ELVIX_URL,
|
|
481
|
+
className = "",
|
|
482
|
+
width,
|
|
483
|
+
height,
|
|
484
|
+
minWidth,
|
|
485
|
+
maxWidth,
|
|
486
|
+
minHeight,
|
|
487
|
+
maxHeight
|
|
488
|
+
}) {
|
|
489
|
+
const s = SIZE[size];
|
|
490
|
+
const t = TONE[variant][theme];
|
|
491
|
+
const style = {
|
|
492
|
+
display: "inline-flex",
|
|
493
|
+
alignItems: "center",
|
|
494
|
+
gap: s.gap,
|
|
495
|
+
height: s.height,
|
|
496
|
+
paddingLeft: s.padX,
|
|
497
|
+
paddingRight: s.padX,
|
|
498
|
+
fontSize: s.font,
|
|
499
|
+
fontWeight: 500,
|
|
500
|
+
borderRadius: 9999,
|
|
501
|
+
background: t.bg,
|
|
502
|
+
border: `1px solid ${t.border}`,
|
|
503
|
+
color: t.brand,
|
|
504
|
+
textDecoration: "none",
|
|
505
|
+
userSelect: "none",
|
|
506
|
+
lineHeight: 1,
|
|
507
|
+
// Dimensional overrides win over the size preset above.
|
|
508
|
+
...sizeStyle({ width, height, minWidth, maxWidth, minHeight, maxHeight })
|
|
509
|
+
};
|
|
510
|
+
return /* @__PURE__ */ jsxs4(
|
|
511
|
+
"a",
|
|
390
512
|
{
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
513
|
+
href,
|
|
514
|
+
target: "_blank",
|
|
515
|
+
rel: "noopener noreferrer",
|
|
516
|
+
className,
|
|
517
|
+
style,
|
|
518
|
+
"data-elvix-secured-badge": "",
|
|
519
|
+
children: [
|
|
520
|
+
/* @__PURE__ */ jsx5(ElvixShield, { size: s.icon, fill: t.shield, accent: accentColor }),
|
|
521
|
+
/* @__PURE__ */ jsxs4("span", { style: { display: "inline-flex", alignItems: "baseline", gap: 4 }, children: [
|
|
522
|
+
/* @__PURE__ */ jsx5("span", { style: { color: t.lead }, children: "Secured by" }),
|
|
523
|
+
/* @__PURE__ */ jsx5("span", { style: { color: t.brand, fontWeight: 600 }, children: "elvix" })
|
|
524
|
+
] })
|
|
525
|
+
]
|
|
526
|
+
}
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/react/elvix-sign-in-form.tsx
|
|
531
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
532
|
+
function GoogleG({ size = 18 }) {
|
|
533
|
+
return /* @__PURE__ */ jsxs5("svg", { width: size, height: size, viewBox: "0 0 18 18", "aria-hidden": true, style: { display: "block" }, children: [
|
|
534
|
+
/* @__PURE__ */ jsx6(
|
|
535
|
+
"path",
|
|
536
|
+
{
|
|
537
|
+
fill: "#4285F4",
|
|
538
|
+
d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"
|
|
539
|
+
}
|
|
540
|
+
),
|
|
541
|
+
/* @__PURE__ */ jsx6(
|
|
542
|
+
"path",
|
|
543
|
+
{
|
|
544
|
+
fill: "#34A853",
|
|
545
|
+
d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"
|
|
546
|
+
}
|
|
547
|
+
),
|
|
548
|
+
/* @__PURE__ */ jsx6(
|
|
549
|
+
"path",
|
|
550
|
+
{
|
|
551
|
+
fill: "#FBBC05",
|
|
552
|
+
d: "M3.97 10.72A5.4 5.4 0 0 1 3.68 9c0-.6.1-1.18.29-1.72V4.95H.96A9 9 0 0 0 0 9c0 1.45.35 2.83.96 4.05l3.01-2.33Z"
|
|
553
|
+
}
|
|
554
|
+
),
|
|
555
|
+
/* @__PURE__ */ jsx6(
|
|
556
|
+
"path",
|
|
557
|
+
{
|
|
558
|
+
fill: "#EA4335",
|
|
559
|
+
d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.59C13.46.89 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
] });
|
|
563
|
+
}
|
|
564
|
+
function ElvixSignInForm({
|
|
565
|
+
onResult,
|
|
566
|
+
redirectAfterSignIn,
|
|
567
|
+
copy: copyProp,
|
|
568
|
+
className = "",
|
|
569
|
+
minWidth,
|
|
570
|
+
maxWidth,
|
|
571
|
+
minHeight,
|
|
572
|
+
maxHeight,
|
|
573
|
+
width,
|
|
574
|
+
height
|
|
575
|
+
}) {
|
|
576
|
+
const ctx = useElvixContext();
|
|
577
|
+
const app = useElvixApp();
|
|
578
|
+
const copy = resolveCopy(app?.strings, copyProp);
|
|
579
|
+
const [step, setStep] = useState3("identify");
|
|
580
|
+
const [email, setEmail] = useState3("");
|
|
581
|
+
const [code, setCode] = useState3("");
|
|
582
|
+
const [challengeId, setChallengeId] = useState3(null);
|
|
583
|
+
const [busy, setBusy] = useState3(false);
|
|
584
|
+
const [error, setError] = useState3(null);
|
|
585
|
+
const brand = app?.brandColor || "#6c5ce7";
|
|
586
|
+
const onBrand = app?.onBrandColor || "#fff";
|
|
587
|
+
const appName = app?.appName ?? "your app";
|
|
588
|
+
const verb = app?.signInVerb === "login" ? "Log in" : "Sign in";
|
|
589
|
+
const defaultTitle = app?.appName ? `${verb} to ${app.appName}` : verb;
|
|
590
|
+
const title = copy.title ? fillCopy(copy.title, { app: app?.appName ?? "" }) : defaultTitle;
|
|
591
|
+
const submitLabel = copy.submitButton ?? verb;
|
|
592
|
+
const showGoogle = Boolean(app?.methodGoogle);
|
|
593
|
+
const showEmail = Boolean(app?.methodEmailOtp);
|
|
594
|
+
const showDivider = showGoogle && showEmail;
|
|
595
|
+
const logoSrc = app?.iconUrl || app?.logoUrl || null;
|
|
596
|
+
const privacyUrl = app?.privacyPolicyUrl || null;
|
|
597
|
+
const termsUrl = app?.termsOfServiceUrl || null;
|
|
598
|
+
const hasLegal = Boolean(privacyUrl || termsUrl);
|
|
599
|
+
const cardStyle = useMemo2(
|
|
600
|
+
() => ({
|
|
601
|
+
boxSizing: "border-box",
|
|
602
|
+
// Defaults first; the shared sizeStyle() overrides only the keys the host set,
|
|
603
|
+
// so the form keeps its width "100%" / maxWidth 400 defaults when unsized.
|
|
604
|
+
width: "100%",
|
|
605
|
+
maxWidth: 400,
|
|
606
|
+
...sizeStyle({ width, height, minWidth, maxWidth, minHeight, maxHeight }),
|
|
607
|
+
margin: "0 auto",
|
|
608
|
+
display: "flex",
|
|
609
|
+
flexDirection: "column",
|
|
610
|
+
gap: 18,
|
|
611
|
+
background: "#fff",
|
|
612
|
+
color: "#18181b",
|
|
613
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
614
|
+
borderRadius: 16,
|
|
615
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 12px 32px -12px rgba(0,0,0,0.18)",
|
|
616
|
+
padding: 28,
|
|
617
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
|
|
618
|
+
textAlign: "center"
|
|
619
|
+
}),
|
|
620
|
+
[width, maxWidth, minWidth, height, minHeight, maxHeight]
|
|
621
|
+
);
|
|
622
|
+
function fail(error2, message) {
|
|
623
|
+
setError(message ?? error2);
|
|
624
|
+
onResult?.({ ok: false, error: error2, message });
|
|
625
|
+
}
|
|
626
|
+
async function startGoogle() {
|
|
627
|
+
if (!ctx.clientId) return fail("missing_client_id", "ElvixProvider needs a clientId.");
|
|
628
|
+
window.location.assign(
|
|
629
|
+
`${ctx.baseUrl}/api/auth/google/start?intent=app&clientId=${encodeURIComponent(ctx.clientId)}`
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
async function startOtp(e) {
|
|
633
|
+
e.preventDefault();
|
|
634
|
+
if (!email.trim()) return fail("invalid_input", copy.errorEnterEmail);
|
|
635
|
+
setBusy(true);
|
|
636
|
+
setError(null);
|
|
637
|
+
try {
|
|
638
|
+
const res = await fetch(`${ctx.baseUrl}/api/auth/otp/start`, {
|
|
639
|
+
method: "POST",
|
|
640
|
+
headers: { "content-type": "application/json" },
|
|
641
|
+
credentials: isSameOrigin(ctx.baseUrl) ? "include" : "omit",
|
|
642
|
+
body: JSON.stringify({
|
|
643
|
+
email: email.trim(),
|
|
644
|
+
intent: "app",
|
|
645
|
+
clientId: ctx.clientId
|
|
646
|
+
})
|
|
647
|
+
});
|
|
648
|
+
const body = await res.json();
|
|
649
|
+
if (!res.ok || !body.success || !body.data?.challengeId) {
|
|
650
|
+
return fail(body.errorMessage ?? "otp_start_failed");
|
|
651
|
+
}
|
|
652
|
+
setChallengeId(body.data.challengeId);
|
|
653
|
+
setStep("code");
|
|
654
|
+
} catch (e2) {
|
|
655
|
+
fail("network", e2 instanceof Error ? e2.message : void 0);
|
|
656
|
+
} finally {
|
|
657
|
+
setBusy(false);
|
|
394
658
|
}
|
|
395
|
-
|
|
659
|
+
}
|
|
660
|
+
async function verifyOtp(e) {
|
|
661
|
+
e.preventDefault();
|
|
662
|
+
if (!challengeId) return;
|
|
663
|
+
if (code.trim().length !== 6) return fail("invalid_input", copy.errorEnterCode);
|
|
664
|
+
setBusy(true);
|
|
665
|
+
setError(null);
|
|
666
|
+
try {
|
|
667
|
+
const res = await fetch(`${ctx.baseUrl}/api/auth/otp/verify`, {
|
|
668
|
+
method: "POST",
|
|
669
|
+
headers: { "content-type": "application/json" },
|
|
670
|
+
credentials: isSameOrigin(ctx.baseUrl) ? "include" : "omit",
|
|
671
|
+
body: JSON.stringify({ challengeId, code: code.trim() })
|
|
672
|
+
});
|
|
673
|
+
const body = await res.json();
|
|
674
|
+
if (!res.ok || !body.success) {
|
|
675
|
+
return fail(body.errorMessage ?? "otp_verify_failed");
|
|
676
|
+
}
|
|
677
|
+
if (body.data?.token) setElvixToken(body.data.token);
|
|
678
|
+
setStep("done");
|
|
679
|
+
onResult?.({
|
|
680
|
+
ok: true,
|
|
681
|
+
method: "email_otp",
|
|
682
|
+
redirect: body.data?.redirect ?? redirectAfterSignIn,
|
|
683
|
+
token: body.data?.token
|
|
684
|
+
});
|
|
685
|
+
} catch (e2) {
|
|
686
|
+
fail("network", e2 instanceof Error ? e2.message : void 0);
|
|
687
|
+
} finally {
|
|
688
|
+
setBusy(false);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
const labelStyle = {
|
|
692
|
+
display: "block",
|
|
693
|
+
textAlign: "left",
|
|
694
|
+
fontSize: 12.5,
|
|
695
|
+
fontWeight: 500,
|
|
696
|
+
color: "#52525b",
|
|
697
|
+
marginBottom: 6
|
|
698
|
+
};
|
|
699
|
+
const inputStyle = {
|
|
700
|
+
boxSizing: "border-box",
|
|
701
|
+
width: "100%",
|
|
702
|
+
height: 44,
|
|
703
|
+
padding: "0 14px",
|
|
704
|
+
borderRadius: 10,
|
|
705
|
+
border: "1px solid rgba(0,0,0,0.14)",
|
|
706
|
+
background: "#fff",
|
|
707
|
+
color: "#18181b",
|
|
708
|
+
fontSize: 14,
|
|
709
|
+
outline: "none"
|
|
710
|
+
};
|
|
711
|
+
const primaryBtnStyle = {
|
|
712
|
+
boxSizing: "border-box",
|
|
713
|
+
width: "100%",
|
|
714
|
+
height: 44,
|
|
715
|
+
marginTop: 10,
|
|
716
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
717
|
+
borderRadius: 10,
|
|
718
|
+
background: brand,
|
|
719
|
+
color: onBrand,
|
|
720
|
+
fontSize: 14,
|
|
721
|
+
fontWeight: 600,
|
|
722
|
+
cursor: busy ? "not-allowed" : "pointer",
|
|
723
|
+
opacity: busy ? 0.65 : 1,
|
|
724
|
+
backgroundImage: "linear-gradient(to bottom, rgba(255,255,255,0.12), rgba(255,255,255,0) 40%)",
|
|
725
|
+
boxShadow: "0 1px 0 rgba(255,255,255,0.06) inset, 0 2px 3px -1px rgba(0,0,0,0.18), 0 0 0 1px rgba(25,28,33,0.06)"
|
|
726
|
+
};
|
|
727
|
+
const googleBtnStyle = {
|
|
728
|
+
boxSizing: "border-box",
|
|
729
|
+
width: "100%",
|
|
730
|
+
height: 44,
|
|
731
|
+
display: "inline-flex",
|
|
732
|
+
alignItems: "center",
|
|
733
|
+
justifyContent: "center",
|
|
734
|
+
gap: 10,
|
|
735
|
+
border: "1px solid rgba(0,0,0,0.14)",
|
|
736
|
+
borderRadius: 10,
|
|
737
|
+
background: "#fff",
|
|
738
|
+
color: "#18181b",
|
|
739
|
+
fontSize: 14,
|
|
740
|
+
fontWeight: 500,
|
|
741
|
+
cursor: busy ? "not-allowed" : "pointer",
|
|
742
|
+
opacity: busy ? 0.65 : 1
|
|
743
|
+
};
|
|
744
|
+
const tileTint = hexToRgba(brand, 0.12);
|
|
745
|
+
const root = `${className}`.trim() || void 0;
|
|
746
|
+
return /* @__PURE__ */ jsxs5("div", { className: root, style: cardStyle, "data-elvix-pane": step, children: [
|
|
747
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
|
|
748
|
+
/* @__PURE__ */ jsx6(
|
|
749
|
+
"div",
|
|
750
|
+
{
|
|
751
|
+
style: {
|
|
752
|
+
width: 52,
|
|
753
|
+
height: 52,
|
|
754
|
+
borderRadius: 14,
|
|
755
|
+
display: "grid",
|
|
756
|
+
placeItems: "center",
|
|
757
|
+
overflow: "hidden",
|
|
758
|
+
background: logoSrc ? "#fff" : tileTint,
|
|
759
|
+
border: "1px solid rgba(0,0,0,0.08)"
|
|
760
|
+
},
|
|
761
|
+
children: logoSrc ? (
|
|
762
|
+
// biome-ignore lint/a11y/useAltText: alt is set
|
|
763
|
+
/* @__PURE__ */ jsx6(
|
|
764
|
+
"img",
|
|
765
|
+
{
|
|
766
|
+
src: logoSrc,
|
|
767
|
+
alt: appName,
|
|
768
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
769
|
+
}
|
|
770
|
+
)
|
|
771
|
+
) : /* @__PURE__ */ jsx6("span", { style: { fontSize: 22, fontWeight: 700, color: brand }, children: appName.charAt(0).toUpperCase() || "?" })
|
|
772
|
+
}
|
|
773
|
+
),
|
|
774
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
775
|
+
/* @__PURE__ */ jsx6("h2", { style: { margin: 0, fontSize: 19, fontWeight: 600, letterSpacing: "-0.01em" }, children: step === "code" ? "Check your inbox" : title }),
|
|
776
|
+
step !== "done" && /* @__PURE__ */ jsx6("p", { style: { margin: "4px 0 0", fontSize: 13, color: "#71717a" }, children: step === "code" ? fillCopy(copy.codeSentSubtitle ?? "", { email }) : copy.subtitle })
|
|
777
|
+
] })
|
|
778
|
+
] }),
|
|
779
|
+
step === "done" && /* @__PURE__ */ jsx6("p", { style: { margin: 0, fontSize: 14, color: "#18181b" }, children: copy.signedInText }),
|
|
780
|
+
step === "identify" && /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: 14 }, children: [
|
|
781
|
+
showGoogle && /* @__PURE__ */ jsxs5(
|
|
782
|
+
"button",
|
|
783
|
+
{
|
|
784
|
+
type: "button",
|
|
785
|
+
onClick: startGoogle,
|
|
786
|
+
disabled: busy,
|
|
787
|
+
style: googleBtnStyle,
|
|
788
|
+
"data-elvix-method": "google",
|
|
789
|
+
children: [
|
|
790
|
+
/* @__PURE__ */ jsx6(GoogleG, {}),
|
|
791
|
+
/* @__PURE__ */ jsx6("span", { children: copy.googleButton })
|
|
792
|
+
]
|
|
793
|
+
}
|
|
794
|
+
),
|
|
795
|
+
showDivider && /* @__PURE__ */ jsxs5(
|
|
796
|
+
"div",
|
|
797
|
+
{
|
|
798
|
+
"aria-hidden": true,
|
|
799
|
+
style: { display: "flex", alignItems: "center", gap: 12, color: "#a1a1aa" },
|
|
800
|
+
children: [
|
|
801
|
+
/* @__PURE__ */ jsx6("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.08)" } }),
|
|
802
|
+
/* @__PURE__ */ jsx6("span", { style: { fontSize: 11, fontWeight: 600, letterSpacing: "0.08em" }, children: "OR" }),
|
|
803
|
+
/* @__PURE__ */ jsx6("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.08)" } })
|
|
804
|
+
]
|
|
805
|
+
}
|
|
806
|
+
),
|
|
807
|
+
showEmail && /* @__PURE__ */ jsxs5("form", { onSubmit: startOtp, "data-elvix-method": "email_otp", children: [
|
|
808
|
+
/* @__PURE__ */ jsx6("label", { htmlFor: "elvix-email", style: labelStyle, children: "Email" }),
|
|
809
|
+
/* @__PURE__ */ jsx6(
|
|
810
|
+
"input",
|
|
811
|
+
{
|
|
812
|
+
id: "elvix-email",
|
|
813
|
+
type: "email",
|
|
814
|
+
value: email,
|
|
815
|
+
onChange: (ev) => setEmail(ev.target.value),
|
|
816
|
+
placeholder: copy.emailPlaceholder,
|
|
817
|
+
required: true,
|
|
818
|
+
disabled: busy,
|
|
819
|
+
autoComplete: "email",
|
|
820
|
+
style: inputStyle
|
|
821
|
+
}
|
|
822
|
+
),
|
|
823
|
+
/* @__PURE__ */ jsx6("button", { type: "submit", disabled: busy, style: primaryBtnStyle, children: busy ? copy.sendingLabel : copy.sendCodeButton })
|
|
824
|
+
] })
|
|
825
|
+
] }),
|
|
826
|
+
step === "code" && /* @__PURE__ */ jsxs5("form", { onSubmit: verifyOtp, children: [
|
|
827
|
+
/* @__PURE__ */ jsx6("label", { htmlFor: "elvix-code", style: labelStyle, children: "Verification code" }),
|
|
828
|
+
/* @__PURE__ */ jsx6(
|
|
829
|
+
"input",
|
|
830
|
+
{
|
|
831
|
+
id: "elvix-code",
|
|
832
|
+
type: "text",
|
|
833
|
+
inputMode: "numeric",
|
|
834
|
+
pattern: "[0-9]*",
|
|
835
|
+
maxLength: 6,
|
|
836
|
+
value: code,
|
|
837
|
+
onChange: (ev) => setCode(ev.target.value.replace(/\D/g, "")),
|
|
838
|
+
placeholder: copy.codePlaceholder,
|
|
839
|
+
required: true,
|
|
840
|
+
disabled: busy,
|
|
841
|
+
autoComplete: "one-time-code",
|
|
842
|
+
autoFocus: true,
|
|
843
|
+
style: { ...inputStyle, letterSpacing: "0.3em", textAlign: "center", fontSize: 18 }
|
|
844
|
+
}
|
|
845
|
+
),
|
|
846
|
+
/* @__PURE__ */ jsx6("button", { type: "submit", disabled: busy, style: primaryBtnStyle, children: busy ? copy.verifyingLabel : submitLabel }),
|
|
847
|
+
/* @__PURE__ */ jsx6(
|
|
848
|
+
"button",
|
|
849
|
+
{
|
|
850
|
+
type: "button",
|
|
851
|
+
onClick: () => {
|
|
852
|
+
setStep("identify");
|
|
853
|
+
setCode("");
|
|
854
|
+
setError(null);
|
|
855
|
+
},
|
|
856
|
+
disabled: busy,
|
|
857
|
+
style: {
|
|
858
|
+
marginTop: 12,
|
|
859
|
+
background: "none",
|
|
860
|
+
border: "none",
|
|
861
|
+
color: "#71717a",
|
|
862
|
+
fontSize: 12.5,
|
|
863
|
+
cursor: busy ? "not-allowed" : "pointer"
|
|
864
|
+
},
|
|
865
|
+
children: "Use a different email"
|
|
866
|
+
}
|
|
867
|
+
)
|
|
868
|
+
] }),
|
|
869
|
+
error && /* @__PURE__ */ jsx6("p", { role: "alert", style: { margin: 0, fontSize: 12.5, color: "#dc2626" }, children: error }),
|
|
870
|
+
hasLegal && step !== "done" && /* @__PURE__ */ jsxs5("p", { style: { margin: 0, fontSize: 11.5, lineHeight: 1.5, color: "#a1a1aa" }, children: [
|
|
871
|
+
"By continuing, you agree to ",
|
|
872
|
+
appName,
|
|
873
|
+
"'s",
|
|
874
|
+
" ",
|
|
875
|
+
termsUrl && /* @__PURE__ */ jsx6(
|
|
876
|
+
"a",
|
|
877
|
+
{
|
|
878
|
+
href: termsUrl,
|
|
879
|
+
target: "_blank",
|
|
880
|
+
rel: "noopener noreferrer",
|
|
881
|
+
style: { color: "#71717a", textDecoration: "underline" },
|
|
882
|
+
children: "Terms of Service"
|
|
883
|
+
}
|
|
884
|
+
),
|
|
885
|
+
termsUrl && privacyUrl && " \xB7 ",
|
|
886
|
+
privacyUrl && /* @__PURE__ */ jsx6(
|
|
887
|
+
"a",
|
|
888
|
+
{
|
|
889
|
+
href: privacyUrl,
|
|
890
|
+
target: "_blank",
|
|
891
|
+
rel: "noopener noreferrer",
|
|
892
|
+
style: { color: "#71717a", textDecoration: "underline" },
|
|
893
|
+
children: "Privacy Policy"
|
|
894
|
+
}
|
|
895
|
+
)
|
|
896
|
+
] }),
|
|
897
|
+
/* @__PURE__ */ jsx6("div", { style: { display: "flex", justifyContent: "center", paddingTop: 2 }, children: /* @__PURE__ */ jsx6(ElvixSecuredBadge, { variant: "outline", theme: "light", size: "sm", accentColor: brand }) })
|
|
898
|
+
] });
|
|
899
|
+
}
|
|
900
|
+
function hexToRgba(hex, alpha) {
|
|
901
|
+
const m = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(hex.trim());
|
|
902
|
+
if (!m) return hex;
|
|
903
|
+
let h = m[1];
|
|
904
|
+
if (h.length === 3)
|
|
905
|
+
h = h.split("").map((c) => c + c).join("");
|
|
906
|
+
const n = Number.parseInt(h, 16);
|
|
907
|
+
const r = n >> 16 & 255;
|
|
908
|
+
const g = n >> 8 & 255;
|
|
909
|
+
const b = n & 255;
|
|
910
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
396
911
|
}
|
|
397
912
|
|
|
398
913
|
// src/react/elvix-sign-in-button.tsx
|
|
399
|
-
|
|
914
|
+
import { useState as useState4 } from "react";
|
|
915
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
916
|
+
var ELVIX_URL2 = "https://elvix.is";
|
|
400
917
|
var PRESET_LABEL = {
|
|
401
918
|
"sign-in-with-elvix": "Sign in with elvix",
|
|
402
919
|
"continue-with-elvix": "Continue with elvix",
|
|
@@ -435,7 +952,7 @@ function shieldColor(variant, theme) {
|
|
|
435
952
|
}
|
|
436
953
|
function ElvixSignInButton({
|
|
437
954
|
clientId,
|
|
438
|
-
baseUrl =
|
|
955
|
+
baseUrl = ELVIX_URL2,
|
|
439
956
|
returnUrl,
|
|
440
957
|
type = "standard",
|
|
441
958
|
variant = "filled",
|
|
@@ -448,9 +965,16 @@ function ElvixSignInButton({
|
|
|
448
965
|
href,
|
|
449
966
|
mode = "redirect",
|
|
450
967
|
onClick,
|
|
451
|
-
onResult
|
|
968
|
+
onResult,
|
|
969
|
+
width,
|
|
970
|
+
height,
|
|
971
|
+
minWidth,
|
|
972
|
+
maxWidth,
|
|
973
|
+
minHeight,
|
|
974
|
+
maxHeight
|
|
452
975
|
}) {
|
|
453
|
-
const
|
|
976
|
+
const sized = sizeStyle({ width, height, minWidth, maxWidth, minHeight, maxHeight });
|
|
977
|
+
const [embedOpen, setEmbedOpen] = useState4(false);
|
|
454
978
|
const isIcon = type === "icon";
|
|
455
979
|
const resolvedLabel = label ?? PRESET_LABEL[preset];
|
|
456
980
|
const tone = variantTone(variant, theme);
|
|
@@ -471,31 +995,39 @@ function ElvixSignInButton({
|
|
|
471
995
|
border: tone.border,
|
|
472
996
|
boxShadow: tone.shadow,
|
|
473
997
|
transition: "background 0.15s, border-color 0.15s",
|
|
474
|
-
...isIcon ? { height: SIZE_ICON[size], width: SIZE_ICON[size] } : { height: std.height, paddingLeft: std.padX, paddingRight: std.padX, gap: std.gap }
|
|
998
|
+
...isIcon ? { height: SIZE_ICON[size], width: SIZE_ICON[size] } : { height: std.height, paddingLeft: std.padX, paddingRight: std.padX, gap: std.gap },
|
|
999
|
+
// Dimensional overrides win over the size preset above.
|
|
1000
|
+
...sized
|
|
475
1001
|
};
|
|
476
|
-
const content = /* @__PURE__ */
|
|
1002
|
+
const content = /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1003
|
+
/* @__PURE__ */ jsx7(ElvixShield, { size: ICON_SIZE[size], fill: shieldColor(variant, theme), accent: "#8e7dff" }),
|
|
1004
|
+
isIcon ? null : /* @__PURE__ */ jsx7("span", { children: resolvedLabel })
|
|
1005
|
+
] });
|
|
477
1006
|
if (mode === "callback") {
|
|
478
|
-
return /* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ jsx7("button", { type: "button", onClick, className, style, "aria-label": isIcon ? resolvedLabel : void 0, children: content });
|
|
479
1008
|
}
|
|
480
1009
|
if (mode === "embed") {
|
|
481
|
-
return /* @__PURE__ */
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
), embedOpen && /* @__PURE__ */ React.createElement(
|
|
492
|
-
ElvixSignIn,
|
|
493
|
-
{
|
|
494
|
-
onResult: (r) => {
|
|
495
|
-
onResult?.(r);
|
|
1010
|
+
return /* @__PURE__ */ jsxs6("div", { "data-elvix-signin-button-embed": "", style: sized, children: [
|
|
1011
|
+
!embedOpen && /* @__PURE__ */ jsx7(
|
|
1012
|
+
"button",
|
|
1013
|
+
{
|
|
1014
|
+
type: "button",
|
|
1015
|
+
onClick: () => setEmbedOpen(true),
|
|
1016
|
+
className,
|
|
1017
|
+
style,
|
|
1018
|
+
"aria-label": isIcon ? resolvedLabel : void 0,
|
|
1019
|
+
children: content
|
|
496
1020
|
}
|
|
497
|
-
|
|
498
|
-
|
|
1021
|
+
),
|
|
1022
|
+
embedOpen && /* @__PURE__ */ jsx7(
|
|
1023
|
+
ElvixSignIn,
|
|
1024
|
+
{
|
|
1025
|
+
onResult: (r) => {
|
|
1026
|
+
onResult?.(r);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
)
|
|
1030
|
+
] });
|
|
499
1031
|
}
|
|
500
1032
|
const destination = (() => {
|
|
501
1033
|
if (href) return href;
|
|
@@ -504,80 +1036,17 @@ function ElvixSignInButton({
|
|
|
504
1036
|
const sep = base.includes("?") ? "&" : "?";
|
|
505
1037
|
return `${base}${sep}return=${encodeURIComponent(returnUrl)}`;
|
|
506
1038
|
})();
|
|
507
|
-
return /* @__PURE__ */
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// src/react/elvix-secured-badge.tsx
|
|
511
|
-
var ELVIX_URL2 = "https://elvix.is";
|
|
512
|
-
var SIZE = {
|
|
513
|
-
sm: { height: 28, padX: 10, font: 11.5, icon: 14, gap: 6 },
|
|
514
|
-
md: { height: 32, padX: 12, font: 12.5, icon: 16, gap: 7 },
|
|
515
|
-
lg: { height: 36, padX: 14, font: 13, icon: 18, gap: 8 }
|
|
516
|
-
};
|
|
517
|
-
var TONE = {
|
|
518
|
-
white: {
|
|
519
|
-
light: { bg: "#ffffff", border: "#e4e4e7", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" },
|
|
520
|
-
dark: { bg: "#ffffff", border: "transparent", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" }
|
|
521
|
-
},
|
|
522
|
-
dark: {
|
|
523
|
-
light: { bg: "#0a0a0b", border: "rgba(0,0,0,0.1)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" },
|
|
524
|
-
dark: { bg: "#0a0a0b", border: "rgba(255,255,255,0.1)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" }
|
|
525
|
-
},
|
|
526
|
-
outline: {
|
|
527
|
-
light: { bg: "transparent", border: "rgba(0,0,0,0.15)", lead: "#71717a", brand: "#0a0a0b", shield: "#0a0a0b" },
|
|
528
|
-
dark: { bg: "transparent", border: "rgba(142,125,255,0.4)", lead: "#d4d4d8", brand: "#ffffff", shield: "#ffffff" }
|
|
529
|
-
}
|
|
530
|
-
};
|
|
531
|
-
function ElvixSecuredBadge({
|
|
532
|
-
variant = "white",
|
|
533
|
-
size = "md",
|
|
534
|
-
theme = "dark",
|
|
535
|
-
accentColor = "#8e7dff",
|
|
536
|
-
href = ELVIX_URL2,
|
|
537
|
-
className = ""
|
|
538
|
-
}) {
|
|
539
|
-
const s = SIZE[size];
|
|
540
|
-
const t = TONE[variant][theme];
|
|
541
|
-
const style = {
|
|
542
|
-
display: "inline-flex",
|
|
543
|
-
alignItems: "center",
|
|
544
|
-
gap: s.gap,
|
|
545
|
-
height: s.height,
|
|
546
|
-
paddingLeft: s.padX,
|
|
547
|
-
paddingRight: s.padX,
|
|
548
|
-
fontSize: s.font,
|
|
549
|
-
fontWeight: 500,
|
|
550
|
-
borderRadius: 9999,
|
|
551
|
-
background: t.bg,
|
|
552
|
-
border: `1px solid ${t.border}`,
|
|
553
|
-
color: t.brand,
|
|
554
|
-
textDecoration: "none",
|
|
555
|
-
userSelect: "none",
|
|
556
|
-
lineHeight: 1
|
|
557
|
-
};
|
|
558
|
-
return /* @__PURE__ */ React.createElement(
|
|
559
|
-
"a",
|
|
560
|
-
{
|
|
561
|
-
href,
|
|
562
|
-
target: "_blank",
|
|
563
|
-
rel: "noopener noreferrer",
|
|
564
|
-
className,
|
|
565
|
-
style,
|
|
566
|
-
"data-elvix-secured-badge": ""
|
|
567
|
-
},
|
|
568
|
-
/* @__PURE__ */ React.createElement(ElvixShield, { size: s.icon, fill: t.shield, accent: accentColor }),
|
|
569
|
-
/* @__PURE__ */ React.createElement("span", { style: { display: "inline-flex", alignItems: "baseline", gap: 4 } }, /* @__PURE__ */ React.createElement("span", { style: { color: t.lead } }, "Secured by"), /* @__PURE__ */ React.createElement("span", { style: { color: t.brand, fontWeight: 600 } }, "elvix"))
|
|
570
|
-
);
|
|
1039
|
+
return /* @__PURE__ */ jsx7("a", { href: destination, className, style, "aria-label": isIcon ? resolvedLabel : void 0, children: content });
|
|
571
1040
|
}
|
|
572
1041
|
|
|
573
1042
|
// src/react/hooks.ts
|
|
574
|
-
import { useCallback, useEffect as useEffect2, useState as
|
|
1043
|
+
import { useCallback, useEffect as useEffect2, useState as useState5 } from "react";
|
|
575
1044
|
var POLL_MS = 7e3;
|
|
576
1045
|
function useUserList(kind, opts) {
|
|
577
1046
|
const { applicationId, baseUrl = "", pollMs = POLL_MS } = opts;
|
|
578
|
-
const [slugs, setSlugs] =
|
|
579
|
-
const [loading, setLoading] =
|
|
580
|
-
const [error, setError] =
|
|
1047
|
+
const [slugs, setSlugs] = useState5([]);
|
|
1048
|
+
const [loading, setLoading] = useState5(true);
|
|
1049
|
+
const [error, setError] = useState5(null);
|
|
581
1050
|
const refresh = useCallback(async () => {
|
|
582
1051
|
setError(null);
|
|
583
1052
|
try {
|
|
@@ -644,7 +1113,7 @@ function ElvixLifecycleWatcher({
|
|
|
644
1113
|
}
|
|
645
1114
|
|
|
646
1115
|
// src/react/elvix-username.tsx
|
|
647
|
-
import { useState as
|
|
1116
|
+
import { useState as useState6 } from "react";
|
|
648
1117
|
|
|
649
1118
|
// src/react/lib.ts
|
|
650
1119
|
async function appPost(opts, path, body) {
|
|
@@ -702,14 +1171,22 @@ async function appDelete(opts, path) {
|
|
|
702
1171
|
}
|
|
703
1172
|
|
|
704
1173
|
// src/react/elvix-username.tsx
|
|
1174
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
705
1175
|
function ElvixUsername({
|
|
706
|
-
onResult
|
|
1176
|
+
onResult,
|
|
1177
|
+
width,
|
|
1178
|
+
height,
|
|
1179
|
+
minWidth,
|
|
1180
|
+
maxWidth,
|
|
1181
|
+
minHeight,
|
|
1182
|
+
maxHeight
|
|
707
1183
|
}) {
|
|
1184
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
708
1185
|
const ctx = useElvixContext();
|
|
709
|
-
const [value, setValue] =
|
|
710
|
-
const [busy, setBusy] =
|
|
711
|
-
const [error, setError] =
|
|
712
|
-
const [done, setDone] =
|
|
1186
|
+
const [value, setValue] = useState6("");
|
|
1187
|
+
const [busy, setBusy] = useState6(false);
|
|
1188
|
+
const [error, setError] = useState6(null);
|
|
1189
|
+
const [done, setDone] = useState6(null);
|
|
713
1190
|
async function submit(e) {
|
|
714
1191
|
e.preventDefault();
|
|
715
1192
|
if (!ctx.app) return;
|
|
@@ -729,32 +1206,51 @@ function ElvixUsername({
|
|
|
729
1206
|
onResult?.(result);
|
|
730
1207
|
}
|
|
731
1208
|
if (done) {
|
|
732
|
-
return /* @__PURE__ */
|
|
1209
|
+
return /* @__PURE__ */ jsx8(ElvixCard, { title: "Username saved", ...sizeProps, children: /* @__PURE__ */ jsxs7("p", { children: [
|
|
1210
|
+
"You are now ",
|
|
1211
|
+
/* @__PURE__ */ jsxs7("strong", { children: [
|
|
1212
|
+
"@",
|
|
1213
|
+
done
|
|
1214
|
+
] }),
|
|
1215
|
+
"."
|
|
1216
|
+
] }) });
|
|
733
1217
|
}
|
|
734
|
-
return /* @__PURE__ */
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
1218
|
+
return /* @__PURE__ */ jsx8(ElvixCard, { title: "Choose a username", ...sizeProps, children: /* @__PURE__ */ jsxs7("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
1219
|
+
/* @__PURE__ */ jsx8(
|
|
1220
|
+
"input",
|
|
1221
|
+
{
|
|
1222
|
+
type: "text",
|
|
1223
|
+
value,
|
|
1224
|
+
onChange: (e) => setValue(e.target.value.toLowerCase()),
|
|
1225
|
+
placeholder: "alice",
|
|
1226
|
+
pattern: "[a-z][a-z0-9._]{2,28}[a-z0-9]",
|
|
1227
|
+
required: true,
|
|
1228
|
+
disabled: busy,
|
|
1229
|
+
className: "elvix-input"
|
|
1230
|
+
}
|
|
1231
|
+
),
|
|
1232
|
+
/* @__PURE__ */ jsx8("button", { type: "submit", disabled: busy || value.length < 4, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Claim" }),
|
|
1233
|
+
error && /* @__PURE__ */ jsx8("p", { role: "alert", className: "elvix-error", children: error })
|
|
1234
|
+
] }) });
|
|
747
1235
|
}
|
|
748
1236
|
|
|
749
1237
|
// src/react/elvix-avatar.tsx
|
|
750
|
-
import { useState as
|
|
1238
|
+
import { useState as useState7 } from "react";
|
|
1239
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
751
1240
|
function ElvixAvatar({
|
|
752
|
-
onResult
|
|
1241
|
+
onResult,
|
|
1242
|
+
width,
|
|
1243
|
+
height,
|
|
1244
|
+
minWidth,
|
|
1245
|
+
maxWidth,
|
|
1246
|
+
minHeight,
|
|
1247
|
+
maxHeight
|
|
753
1248
|
}) {
|
|
1249
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
754
1250
|
const ctx = useElvixContext();
|
|
755
|
-
const [busy, setBusy] =
|
|
756
|
-
const [error, setError] =
|
|
757
|
-
const [preview, setPreview] =
|
|
1251
|
+
const [busy, setBusy] = useState7(false);
|
|
1252
|
+
const [error, setError] = useState7(null);
|
|
1253
|
+
const [preview, setPreview] = useState7(null);
|
|
758
1254
|
async function onFile(e) {
|
|
759
1255
|
const file = e.target.files?.[0];
|
|
760
1256
|
if (!file || !ctx.app) return;
|
|
@@ -777,25 +1273,38 @@ function ElvixAvatar({
|
|
|
777
1273
|
if (!result.ok) setError(result.error);
|
|
778
1274
|
onResult?.(result);
|
|
779
1275
|
}
|
|
780
|
-
return /* @__PURE__ */
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
1276
|
+
return /* @__PURE__ */ jsxs8(ElvixCard, { title: "Avatar", ...sizeProps, children: [
|
|
1277
|
+
preview && /* @__PURE__ */ jsx9(
|
|
1278
|
+
"img",
|
|
1279
|
+
{
|
|
1280
|
+
src: preview,
|
|
1281
|
+
alt: "avatar preview",
|
|
1282
|
+
style: { width: 96, height: 96, borderRadius: "50%", objectFit: "cover", marginBottom: 12 }
|
|
1283
|
+
}
|
|
1284
|
+
),
|
|
1285
|
+
/* @__PURE__ */ jsx9("input", { type: "file", accept: "image/png,image/jpeg,image/webp", onChange: onFile, disabled: busy }),
|
|
1286
|
+
busy && /* @__PURE__ */ jsx9("p", { children: "Uploading\u2026" }),
|
|
1287
|
+
error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "elvix-error", children: error })
|
|
1288
|
+
] });
|
|
788
1289
|
}
|
|
789
1290
|
|
|
790
1291
|
// src/react/elvix-banner.tsx
|
|
791
|
-
import { useState as
|
|
1292
|
+
import { useState as useState8 } from "react";
|
|
1293
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
792
1294
|
function ElvixBanner({
|
|
793
|
-
onResult
|
|
1295
|
+
onResult,
|
|
1296
|
+
width,
|
|
1297
|
+
height,
|
|
1298
|
+
minWidth,
|
|
1299
|
+
maxWidth,
|
|
1300
|
+
minHeight,
|
|
1301
|
+
maxHeight
|
|
794
1302
|
}) {
|
|
1303
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
795
1304
|
const ctx = useElvixContext();
|
|
796
|
-
const [busy, setBusy] =
|
|
797
|
-
const [error, setError] =
|
|
798
|
-
const [preview, setPreview] =
|
|
1305
|
+
const [busy, setBusy] = useState8(false);
|
|
1306
|
+
const [error, setError] = useState8(null);
|
|
1307
|
+
const [preview, setPreview] = useState8(null);
|
|
799
1308
|
async function onFile(e) {
|
|
800
1309
|
const file = e.target.files?.[0];
|
|
801
1310
|
if (!file || !ctx.app) return;
|
|
@@ -818,29 +1327,42 @@ function ElvixBanner({
|
|
|
818
1327
|
if (!result.ok) setError(result.error);
|
|
819
1328
|
onResult?.(result);
|
|
820
1329
|
}
|
|
821
|
-
return /* @__PURE__ */
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1330
|
+
return /* @__PURE__ */ jsxs9(ElvixCard, { title: "Banner", ...sizeProps, children: [
|
|
1331
|
+
preview && /* @__PURE__ */ jsx10(
|
|
1332
|
+
"img",
|
|
1333
|
+
{
|
|
1334
|
+
src: preview,
|
|
1335
|
+
alt: "banner preview",
|
|
1336
|
+
style: { width: "100%", aspectRatio: "16/9", objectFit: "cover", borderRadius: 10, marginBottom: 12 }
|
|
1337
|
+
}
|
|
1338
|
+
),
|
|
1339
|
+
/* @__PURE__ */ jsx10("input", { type: "file", accept: "image/png,image/jpeg,image/webp", onChange: onFile, disabled: busy }),
|
|
1340
|
+
busy && /* @__PURE__ */ jsx10("p", { children: "Uploading\u2026" }),
|
|
1341
|
+
error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "elvix-error", children: error })
|
|
1342
|
+
] });
|
|
829
1343
|
}
|
|
830
1344
|
|
|
831
1345
|
// src/react/elvix-identity-form.tsx
|
|
832
|
-
import { useState as
|
|
1346
|
+
import { useState as useState9 } from "react";
|
|
1347
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
833
1348
|
function ElvixIdentityForm({
|
|
834
1349
|
initialName = "",
|
|
835
1350
|
initialBio = "",
|
|
836
|
-
onResult
|
|
1351
|
+
onResult,
|
|
1352
|
+
width,
|
|
1353
|
+
height,
|
|
1354
|
+
minWidth,
|
|
1355
|
+
maxWidth,
|
|
1356
|
+
minHeight,
|
|
1357
|
+
maxHeight
|
|
837
1358
|
}) {
|
|
1359
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
838
1360
|
const ctx = useElvixContext();
|
|
839
|
-
const [name, setName] =
|
|
840
|
-
const [bio, setBio] =
|
|
841
|
-
const [busy, setBusy] =
|
|
842
|
-
const [error, setError] =
|
|
843
|
-
const [saved, setSaved] =
|
|
1361
|
+
const [name, setName] = useState9(initialName);
|
|
1362
|
+
const [bio, setBio] = useState9(initialBio);
|
|
1363
|
+
const [busy, setBusy] = useState9(false);
|
|
1364
|
+
const [error, setError] = useState9(null);
|
|
1365
|
+
const [saved, setSaved] = useState9(false);
|
|
844
1366
|
async function submit(e) {
|
|
845
1367
|
e.preventDefault();
|
|
846
1368
|
if (!ctx.app) return;
|
|
@@ -856,22 +1378,42 @@ function ElvixIdentityForm({
|
|
|
856
1378
|
else setSaved(true);
|
|
857
1379
|
onResult?.(result);
|
|
858
1380
|
}
|
|
859
|
-
return /* @__PURE__ */
|
|
1381
|
+
return /* @__PURE__ */ jsx11(ElvixCard, { title: "Identity", ...sizeProps, children: /* @__PURE__ */ jsxs10("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
1382
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
1383
|
+
"Name",
|
|
1384
|
+
/* @__PURE__ */ jsx11("input", { value: name, onChange: (e) => setName(e.target.value), maxLength: 80, disabled: busy, className: "elvix-input" })
|
|
1385
|
+
] }),
|
|
1386
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
1387
|
+
"Bio",
|
|
1388
|
+
/* @__PURE__ */ jsx11("textarea", { value: bio, onChange: (e) => setBio(e.target.value), maxLength: 500, rows: 3, disabled: busy, className: "elvix-input" })
|
|
1389
|
+
] }),
|
|
1390
|
+
/* @__PURE__ */ jsx11("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
1391
|
+
saved && /* @__PURE__ */ jsx11("p", { className: "elvix-muted", children: "Saved." }),
|
|
1392
|
+
error && /* @__PURE__ */ jsx11("p", { role: "alert", className: "elvix-error", children: error })
|
|
1393
|
+
] }) });
|
|
860
1394
|
}
|
|
861
1395
|
|
|
862
1396
|
// src/react/elvix-region.tsx
|
|
863
|
-
import { useState as
|
|
1397
|
+
import { useState as useState10 } from "react";
|
|
1398
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
864
1399
|
function ElvixRegion({
|
|
865
1400
|
initialCountry = "",
|
|
866
1401
|
initialTimezone = "",
|
|
867
|
-
onResult
|
|
1402
|
+
onResult,
|
|
1403
|
+
width,
|
|
1404
|
+
height,
|
|
1405
|
+
minWidth,
|
|
1406
|
+
maxWidth,
|
|
1407
|
+
minHeight,
|
|
1408
|
+
maxHeight
|
|
868
1409
|
}) {
|
|
1410
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
869
1411
|
const ctx = useElvixContext();
|
|
870
|
-
const [country, setCountry] =
|
|
871
|
-
const [timezone, setTimezone] =
|
|
872
|
-
const [busy, setBusy] =
|
|
873
|
-
const [error, setError] =
|
|
874
|
-
const [saved, setSaved] =
|
|
1412
|
+
const [country, setCountry] = useState10(initialCountry);
|
|
1413
|
+
const [timezone, setTimezone] = useState10(initialTimezone);
|
|
1414
|
+
const [busy, setBusy] = useState10(false);
|
|
1415
|
+
const [error, setError] = useState10(null);
|
|
1416
|
+
const [saved, setSaved] = useState10(false);
|
|
875
1417
|
async function submit(e) {
|
|
876
1418
|
e.preventDefault();
|
|
877
1419
|
if (!ctx.app) return;
|
|
@@ -887,20 +1429,40 @@ function ElvixRegion({
|
|
|
887
1429
|
else setSaved(true);
|
|
888
1430
|
onResult?.(result);
|
|
889
1431
|
}
|
|
890
|
-
return /* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsx12(ElvixCard, { title: "Region", ...sizeProps, children: /* @__PURE__ */ jsxs11("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
1433
|
+
/* @__PURE__ */ jsxs11("label", { children: [
|
|
1434
|
+
"Country (ISO-2)",
|
|
1435
|
+
/* @__PURE__ */ jsx12("input", { value: country, onChange: (e) => setCountry(e.target.value.toUpperCase()), maxLength: 2, pattern: "[A-Z]{2}", disabled: busy, className: "elvix-input" })
|
|
1436
|
+
] }),
|
|
1437
|
+
/* @__PURE__ */ jsxs11("label", { children: [
|
|
1438
|
+
"Timezone",
|
|
1439
|
+
/* @__PURE__ */ jsx12("input", { value: timezone, onChange: (e) => setTimezone(e.target.value), placeholder: "Europe/Berlin", disabled: busy, className: "elvix-input" })
|
|
1440
|
+
] }),
|
|
1441
|
+
/* @__PURE__ */ jsx12("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
1442
|
+
saved && /* @__PURE__ */ jsx12("p", { className: "elvix-muted", children: "Saved." }),
|
|
1443
|
+
error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "elvix-error", children: error })
|
|
1444
|
+
] }) });
|
|
891
1445
|
}
|
|
892
1446
|
|
|
893
1447
|
// src/react/elvix-languages.tsx
|
|
894
|
-
import { useState as
|
|
1448
|
+
import { useState as useState11 } from "react";
|
|
1449
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
895
1450
|
function ElvixLanguages({
|
|
896
1451
|
initial = [],
|
|
897
|
-
onResult
|
|
1452
|
+
onResult,
|
|
1453
|
+
width,
|
|
1454
|
+
height,
|
|
1455
|
+
minWidth,
|
|
1456
|
+
maxWidth,
|
|
1457
|
+
minHeight,
|
|
1458
|
+
maxHeight
|
|
898
1459
|
}) {
|
|
1460
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
899
1461
|
const ctx = useElvixContext();
|
|
900
|
-
const [raw, setRaw] =
|
|
901
|
-
const [busy, setBusy] =
|
|
902
|
-
const [error, setError] =
|
|
903
|
-
const [saved, setSaved] =
|
|
1462
|
+
const [raw, setRaw] = useState11(initial.join(", "));
|
|
1463
|
+
const [busy, setBusy] = useState11(false);
|
|
1464
|
+
const [error, setError] = useState11(null);
|
|
1465
|
+
const [saved, setSaved] = useState11(false);
|
|
904
1466
|
async function submit(e) {
|
|
905
1467
|
e.preventDefault();
|
|
906
1468
|
if (!ctx.app) return;
|
|
@@ -917,18 +1479,34 @@ function ElvixLanguages({
|
|
|
917
1479
|
else setSaved(true);
|
|
918
1480
|
onResult?.(result);
|
|
919
1481
|
}
|
|
920
|
-
return /* @__PURE__ */
|
|
1482
|
+
return /* @__PURE__ */ jsx13(ElvixCard, { title: "Languages", ...sizeProps, children: /* @__PURE__ */ jsxs12("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
1483
|
+
/* @__PURE__ */ jsxs12("label", { children: [
|
|
1484
|
+
"Preferred languages (comma-separated BCP-47 tags)",
|
|
1485
|
+
/* @__PURE__ */ jsx13("input", { value: raw, onChange: (e) => setRaw(e.target.value), placeholder: "en-GB, de-DE", disabled: busy, className: "elvix-input" })
|
|
1486
|
+
] }),
|
|
1487
|
+
/* @__PURE__ */ jsx13("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
1488
|
+
saved && /* @__PURE__ */ jsx13("p", { className: "elvix-muted", children: "Saved." }),
|
|
1489
|
+
error && /* @__PURE__ */ jsx13("p", { role: "alert", className: "elvix-error", children: error })
|
|
1490
|
+
] }) });
|
|
921
1491
|
}
|
|
922
1492
|
|
|
923
1493
|
// src/react/elvix-sessions.tsx
|
|
924
|
-
import { useEffect as useEffect4, useState as
|
|
1494
|
+
import { useEffect as useEffect4, useState as useState12 } from "react";
|
|
1495
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
925
1496
|
function ElvixSessions({
|
|
926
|
-
onResult
|
|
1497
|
+
onResult,
|
|
1498
|
+
width,
|
|
1499
|
+
height,
|
|
1500
|
+
minWidth,
|
|
1501
|
+
maxWidth,
|
|
1502
|
+
minHeight,
|
|
1503
|
+
maxHeight
|
|
927
1504
|
}) {
|
|
1505
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
928
1506
|
const ctx = useElvixContext();
|
|
929
|
-
const [rows, setRows] =
|
|
930
|
-
const [error, setError] =
|
|
931
|
-
const [busy, setBusy] =
|
|
1507
|
+
const [rows, setRows] = useState12(null);
|
|
1508
|
+
const [error, setError] = useState12(null);
|
|
1509
|
+
const [busy, setBusy] = useState12(false);
|
|
932
1510
|
useEffect4(() => {
|
|
933
1511
|
if (!ctx.app) return;
|
|
934
1512
|
fetch(`${ctx.baseUrl}/api/account/apps/${ctx.app.applicationId}/sessions`, {
|
|
@@ -949,18 +1527,43 @@ function ElvixSessions({
|
|
|
949
1527
|
if (result.ok) setRows((prev) => prev?.filter((s) => s.id !== id) ?? null);
|
|
950
1528
|
onResult?.(result);
|
|
951
1529
|
}
|
|
952
|
-
return /* @__PURE__ */
|
|
1530
|
+
return /* @__PURE__ */ jsxs13(ElvixCard, { title: "Active sessions", ...sizeProps, children: [
|
|
1531
|
+
error && /* @__PURE__ */ jsx14("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1532
|
+
!rows && !error && /* @__PURE__ */ jsx14("p", { children: "Loading\u2026" }),
|
|
1533
|
+
rows && /* @__PURE__ */ jsx14("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: rows.map((s) => /* @__PURE__ */ jsx14("li", { style: { padding: "10px 0", borderBottom: "1px solid rgba(0,0,0,0.06)" }, children: /* @__PURE__ */ jsxs13("div", { style: { display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1534
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
1535
|
+
/* @__PURE__ */ jsxs13("div", { style: { fontSize: 13, fontWeight: 500 }, children: [
|
|
1536
|
+
s.device,
|
|
1537
|
+
s.current && /* @__PURE__ */ jsx14("span", { style: { marginLeft: 8, color: "var(--elvix-primary-strong)", fontSize: 11 }, children: "\xB7 this device" })
|
|
1538
|
+
] }),
|
|
1539
|
+
/* @__PURE__ */ jsxs13("div", { style: { fontSize: 11, color: "rgba(0,0,0,0.55)" }, children: [
|
|
1540
|
+
s.country ?? "\u2014",
|
|
1541
|
+
" \xB7 since ",
|
|
1542
|
+
new Date(s.createdAt).toLocaleDateString()
|
|
1543
|
+
] })
|
|
1544
|
+
] }),
|
|
1545
|
+
!s.current && /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => revoke(s.id), className: "elvix-btn elvix-btn-ghost", children: "Revoke" })
|
|
1546
|
+
] }) }, s.id)) })
|
|
1547
|
+
] });
|
|
953
1548
|
}
|
|
954
1549
|
|
|
955
1550
|
// src/react/elvix-export.tsx
|
|
956
|
-
import { useState as
|
|
1551
|
+
import { useState as useState13 } from "react";
|
|
1552
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
957
1553
|
function ElvixExport({
|
|
958
|
-
onResult
|
|
1554
|
+
onResult,
|
|
1555
|
+
width,
|
|
1556
|
+
height,
|
|
1557
|
+
minWidth,
|
|
1558
|
+
maxWidth,
|
|
1559
|
+
minHeight,
|
|
1560
|
+
maxHeight
|
|
959
1561
|
}) {
|
|
1562
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
960
1563
|
const ctx = useElvixContext();
|
|
961
|
-
const [busy, setBusy] =
|
|
962
|
-
const [done, setDone] =
|
|
963
|
-
const [error, setError] =
|
|
1564
|
+
const [busy, setBusy] = useState13(false);
|
|
1565
|
+
const [done, setDone] = useState13(false);
|
|
1566
|
+
const [error, setError] = useState13(null);
|
|
964
1567
|
async function start() {
|
|
965
1568
|
if (!ctx.app) return;
|
|
966
1569
|
setBusy(true);
|
|
@@ -975,20 +1578,32 @@ function ElvixExport({
|
|
|
975
1578
|
else setDone(true);
|
|
976
1579
|
onResult?.(result);
|
|
977
1580
|
}
|
|
978
|
-
return /* @__PURE__ */
|
|
1581
|
+
return /* @__PURE__ */ jsxs14(ElvixCard, { title: "Export my data", ...sizeProps, children: [
|
|
1582
|
+
/* @__PURE__ */ jsx15("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Request a zip of every record we hold for you in this app. Delivery by email; single-use download link valid for 24h." }),
|
|
1583
|
+
done ? /* @__PURE__ */ jsx15("p", { className: "elvix-muted", children: "Request queued. Check your email." }) : /* @__PURE__ */ jsx15("button", { type: "button", onClick: start, disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Queuing\u2026" : "Request export" }),
|
|
1584
|
+
error && /* @__PURE__ */ jsx15("p", { role: "alert", className: "elvix-error", children: error })
|
|
1585
|
+
] });
|
|
979
1586
|
}
|
|
980
1587
|
|
|
981
1588
|
// src/react/elvix-deactivate.tsx
|
|
982
|
-
import { useState as
|
|
1589
|
+
import { useState as useState14 } from "react";
|
|
1590
|
+
import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
983
1591
|
function ElvixDeactivate({
|
|
984
|
-
onResult
|
|
1592
|
+
onResult,
|
|
1593
|
+
width,
|
|
1594
|
+
height,
|
|
1595
|
+
minWidth,
|
|
1596
|
+
maxWidth,
|
|
1597
|
+
minHeight,
|
|
1598
|
+
maxHeight
|
|
985
1599
|
}) {
|
|
1600
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
986
1601
|
const ctx = useElvixContext();
|
|
987
|
-
const [pane, setPane] =
|
|
988
|
-
const [challengeId, setChallengeId] =
|
|
989
|
-
const [code, setCode] =
|
|
990
|
-
const [busy, setBusy] =
|
|
991
|
-
const [error, setError] =
|
|
1602
|
+
const [pane, setPane] = useState14("warn");
|
|
1603
|
+
const [challengeId, setChallengeId] = useState14(null);
|
|
1604
|
+
const [code, setCode] = useState14("");
|
|
1605
|
+
const [busy, setBusy] = useState14(false);
|
|
1606
|
+
const [error, setError] = useState14(null);
|
|
992
1607
|
async function startChallenge() {
|
|
993
1608
|
if (!ctx.app) return;
|
|
994
1609
|
setBusy(true);
|
|
@@ -1026,35 +1641,54 @@ function ElvixDeactivate({
|
|
|
1026
1641
|
onResult?.(result);
|
|
1027
1642
|
}
|
|
1028
1643
|
if (pane === "done") {
|
|
1029
|
-
return /* @__PURE__ */
|
|
1644
|
+
return /* @__PURE__ */ jsx16(ElvixCard, { title: "Deactivated", ...sizeProps, children: /* @__PURE__ */ jsx16("p", { children: "Your access has been paused. Sign in again to restore it." }) });
|
|
1030
1645
|
}
|
|
1031
|
-
return /* @__PURE__ */
|
|
1032
|
-
"
|
|
1033
|
-
|
|
1034
|
-
type: "
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1646
|
+
return /* @__PURE__ */ jsxs15(ElvixCard, { title: "Deactivate account", ...sizeProps, children: [
|
|
1647
|
+
pane === "warn" && /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
1648
|
+
/* @__PURE__ */ jsx16("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Pause your membership. You can restore it any time by signing in again. No data is deleted." }),
|
|
1649
|
+
/* @__PURE__ */ jsx16("button", { type: "button", onClick: startChallenge, disabled: busy, className: "elvix-btn elvix-btn-danger", children: busy ? "Sending\u2026" : "Send code" })
|
|
1650
|
+
] }),
|
|
1651
|
+
pane === "otp" && /* @__PURE__ */ jsxs15("form", { onSubmit: confirm, className: "elvix-form", children: [
|
|
1652
|
+
/* @__PURE__ */ jsx16("p", { className: "elvix-muted", children: "We sent a 6-digit code to your email." }),
|
|
1653
|
+
/* @__PURE__ */ jsx16(
|
|
1654
|
+
"input",
|
|
1655
|
+
{
|
|
1656
|
+
type: "text",
|
|
1657
|
+
inputMode: "numeric",
|
|
1658
|
+
pattern: "[0-9]*",
|
|
1659
|
+
maxLength: 6,
|
|
1660
|
+
value: code,
|
|
1661
|
+
onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
|
|
1662
|
+
required: true,
|
|
1663
|
+
disabled: busy,
|
|
1664
|
+
className: "elvix-input"
|
|
1665
|
+
}
|
|
1666
|
+
),
|
|
1667
|
+
/* @__PURE__ */ jsx16("button", { type: "submit", disabled: busy || code.length !== 6, className: "elvix-btn elvix-btn-danger", children: busy ? "Deactivating\u2026" : "Confirm" })
|
|
1668
|
+
] }),
|
|
1669
|
+
error && /* @__PURE__ */ jsx16("p", { role: "alert", className: "elvix-error", children: error })
|
|
1670
|
+
] });
|
|
1045
1671
|
}
|
|
1046
1672
|
|
|
1047
1673
|
// src/react/elvix-leave.tsx
|
|
1048
|
-
import { useState as
|
|
1674
|
+
import { useState as useState15 } from "react";
|
|
1675
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1049
1676
|
function ElvixLeave({
|
|
1050
|
-
onResult
|
|
1677
|
+
onResult,
|
|
1678
|
+
width,
|
|
1679
|
+
height,
|
|
1680
|
+
minWidth,
|
|
1681
|
+
maxWidth,
|
|
1682
|
+
minHeight,
|
|
1683
|
+
maxHeight
|
|
1051
1684
|
}) {
|
|
1685
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
1052
1686
|
const ctx = useElvixContext();
|
|
1053
|
-
const [pane, setPane] =
|
|
1054
|
-
const [challengeId, setChallengeId] =
|
|
1055
|
-
const [code, setCode] =
|
|
1056
|
-
const [busy, setBusy] =
|
|
1057
|
-
const [error, setError] =
|
|
1687
|
+
const [pane, setPane] = useState15("warn");
|
|
1688
|
+
const [challengeId, setChallengeId] = useState15(null);
|
|
1689
|
+
const [code, setCode] = useState15("");
|
|
1690
|
+
const [busy, setBusy] = useState15(false);
|
|
1691
|
+
const [error, setError] = useState15(null);
|
|
1058
1692
|
async function startChallenge() {
|
|
1059
1693
|
if (!ctx.app) return;
|
|
1060
1694
|
setBusy(true);
|
|
@@ -1092,35 +1726,54 @@ function ElvixLeave({
|
|
|
1092
1726
|
onResult?.(result);
|
|
1093
1727
|
}
|
|
1094
1728
|
if (pane === "done") {
|
|
1095
|
-
return /* @__PURE__ */
|
|
1729
|
+
return /* @__PURE__ */ jsx17(ElvixCard, { title: "You've left", ...sizeProps, children: /* @__PURE__ */ jsx17("p", { children: "You've left this app. Your data is archived; sign in again to rejoin." }) });
|
|
1096
1730
|
}
|
|
1097
|
-
return /* @__PURE__ */
|
|
1098
|
-
"
|
|
1099
|
-
|
|
1100
|
-
type: "
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1731
|
+
return /* @__PURE__ */ jsxs16(ElvixCard, { title: "Leave this app", ...sizeProps, children: [
|
|
1732
|
+
pane === "warn" && /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
1733
|
+
/* @__PURE__ */ jsx17("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Remove yourself from this app. Audit trail is preserved; you can sign back in any time to rejoin." }),
|
|
1734
|
+
/* @__PURE__ */ jsx17("button", { type: "button", onClick: startChallenge, disabled: busy, className: "elvix-btn elvix-btn-danger", children: busy ? "Sending\u2026" : "Send code" })
|
|
1735
|
+
] }),
|
|
1736
|
+
pane === "otp" && /* @__PURE__ */ jsxs16("form", { onSubmit: confirm, className: "elvix-form", children: [
|
|
1737
|
+
/* @__PURE__ */ jsx17("p", { className: "elvix-muted", children: "We sent a 6-digit code to your email." }),
|
|
1738
|
+
/* @__PURE__ */ jsx17(
|
|
1739
|
+
"input",
|
|
1740
|
+
{
|
|
1741
|
+
type: "text",
|
|
1742
|
+
inputMode: "numeric",
|
|
1743
|
+
pattern: "[0-9]*",
|
|
1744
|
+
maxLength: 6,
|
|
1745
|
+
value: code,
|
|
1746
|
+
onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
|
|
1747
|
+
required: true,
|
|
1748
|
+
disabled: busy,
|
|
1749
|
+
className: "elvix-input"
|
|
1750
|
+
}
|
|
1751
|
+
),
|
|
1752
|
+
/* @__PURE__ */ jsx17("button", { type: "submit", disabled: busy || code.length !== 6, className: "elvix-btn elvix-btn-danger", children: busy ? "Leaving\u2026" : "Confirm leave" })
|
|
1753
|
+
] }),
|
|
1754
|
+
error && /* @__PURE__ */ jsx17("p", { role: "alert", className: "elvix-error", children: error })
|
|
1755
|
+
] });
|
|
1111
1756
|
}
|
|
1112
1757
|
|
|
1113
1758
|
// src/react/elvix-address-book.tsx
|
|
1114
|
-
import { useEffect as useEffect5, useState as
|
|
1759
|
+
import { useEffect as useEffect5, useState as useState16 } from "react";
|
|
1760
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1115
1761
|
function ElvixAddressBook({
|
|
1116
|
-
onResult
|
|
1762
|
+
onResult,
|
|
1763
|
+
width,
|
|
1764
|
+
height,
|
|
1765
|
+
minWidth,
|
|
1766
|
+
maxWidth,
|
|
1767
|
+
minHeight,
|
|
1768
|
+
maxHeight
|
|
1117
1769
|
}) {
|
|
1770
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
1118
1771
|
const ctx = useElvixContext();
|
|
1119
|
-
const [rows, setRows] =
|
|
1120
|
-
const [error, setError] =
|
|
1121
|
-
const [busy, setBusy] =
|
|
1122
|
-
const [adding, setAdding] =
|
|
1123
|
-
const [form, setForm] =
|
|
1772
|
+
const [rows, setRows] = useState16(null);
|
|
1773
|
+
const [error, setError] = useState16(null);
|
|
1774
|
+
const [busy, setBusy] = useState16(false);
|
|
1775
|
+
const [adding, setAdding] = useState16(false);
|
|
1776
|
+
const [form, setForm] = useState16({
|
|
1124
1777
|
label: "Home",
|
|
1125
1778
|
line1: "",
|
|
1126
1779
|
postalCode: "",
|
|
@@ -1169,20 +1822,57 @@ function ElvixAddressBook({
|
|
|
1169
1822
|
if (result.ok) setRows((prev) => prev?.filter((a) => a.id !== id) ?? null);
|
|
1170
1823
|
onResult?.(result);
|
|
1171
1824
|
}
|
|
1172
|
-
return /* @__PURE__ */
|
|
1825
|
+
return /* @__PURE__ */ jsxs17(ElvixCard, { title: "Addresses", ...sizeProps, children: [
|
|
1826
|
+
error && /* @__PURE__ */ jsx18("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1827
|
+
!rows && !error && /* @__PURE__ */ jsx18("p", { children: "Loading\u2026" }),
|
|
1828
|
+
rows && rows.length === 0 && /* @__PURE__ */ jsx18("p", { className: "elvix-muted", children: "No addresses yet." }),
|
|
1829
|
+
rows?.map((a) => /* @__PURE__ */ jsxs17("div", { style: { padding: "8px 0", borderBottom: "1px solid rgba(0,0,0,0.06)", display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1830
|
+
/* @__PURE__ */ jsxs17("div", { style: { fontSize: 13 }, children: [
|
|
1831
|
+
/* @__PURE__ */ jsx18("div", { style: { fontWeight: 500 }, children: a.label }),
|
|
1832
|
+
/* @__PURE__ */ jsxs17("div", { style: { color: "rgba(0,0,0,0.55)" }, children: [
|
|
1833
|
+
a.line1,
|
|
1834
|
+
a.line2 ? `, ${a.line2}` : "",
|
|
1835
|
+
", ",
|
|
1836
|
+
a.postalCode,
|
|
1837
|
+
" ",
|
|
1838
|
+
a.city,
|
|
1839
|
+
", ",
|
|
1840
|
+
a.country
|
|
1841
|
+
] })
|
|
1842
|
+
] }),
|
|
1843
|
+
/* @__PURE__ */ jsx18("button", { type: "button", disabled: busy, onClick: () => remove(a.id), className: "elvix-btn elvix-btn-ghost", children: "Remove" })
|
|
1844
|
+
] }, a.id)),
|
|
1845
|
+
!adding && /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setAdding(true), className: "elvix-btn elvix-btn-primary", style: { marginTop: 12 }, children: "Add address" }),
|
|
1846
|
+
adding && /* @__PURE__ */ jsxs17("form", { onSubmit: add, className: "elvix-form", style: { marginTop: 12 }, children: [
|
|
1847
|
+
/* @__PURE__ */ jsx18("input", { value: form.label, onChange: (e) => setForm({ ...form, label: e.target.value }), placeholder: "Label", className: "elvix-input" }),
|
|
1848
|
+
/* @__PURE__ */ jsx18("input", { value: form.line1, onChange: (e) => setForm({ ...form, line1: e.target.value }), placeholder: "Street", required: true, className: "elvix-input" }),
|
|
1849
|
+
/* @__PURE__ */ jsx18("input", { value: form.postalCode, onChange: (e) => setForm({ ...form, postalCode: e.target.value }), placeholder: "Postal code", required: true, className: "elvix-input" }),
|
|
1850
|
+
/* @__PURE__ */ jsx18("input", { value: form.city, onChange: (e) => setForm({ ...form, city: e.target.value }), placeholder: "City", required: true, className: "elvix-input" }),
|
|
1851
|
+
/* @__PURE__ */ jsx18("input", { value: form.country, onChange: (e) => setForm({ ...form, country: e.target.value.toUpperCase() }), placeholder: "Country (ISO-2)", maxLength: 2, required: true, className: "elvix-input" }),
|
|
1852
|
+
/* @__PURE__ */ jsx18("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" })
|
|
1853
|
+
] })
|
|
1854
|
+
] });
|
|
1173
1855
|
}
|
|
1174
1856
|
|
|
1175
1857
|
// src/react/elvix-legal-entities.tsx
|
|
1176
|
-
import { useEffect as useEffect6, useState as
|
|
1858
|
+
import { useEffect as useEffect6, useState as useState17 } from "react";
|
|
1859
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1177
1860
|
function ElvixLegalEntities({
|
|
1178
|
-
onResult
|
|
1861
|
+
onResult,
|
|
1862
|
+
width,
|
|
1863
|
+
height,
|
|
1864
|
+
minWidth,
|
|
1865
|
+
maxWidth,
|
|
1866
|
+
minHeight,
|
|
1867
|
+
maxHeight
|
|
1179
1868
|
}) {
|
|
1869
|
+
const sizeProps = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
1180
1870
|
const ctx = useElvixContext();
|
|
1181
|
-
const [rows, setRows] =
|
|
1182
|
-
const [error, setError] =
|
|
1183
|
-
const [busy, setBusy] =
|
|
1184
|
-
const [adding, setAdding] =
|
|
1185
|
-
const [form, setForm] =
|
|
1871
|
+
const [rows, setRows] = useState17(null);
|
|
1872
|
+
const [error, setError] = useState17(null);
|
|
1873
|
+
const [busy, setBusy] = useState17(false);
|
|
1874
|
+
const [adding, setAdding] = useState17(false);
|
|
1875
|
+
const [form, setForm] = useState17({
|
|
1186
1876
|
legalName: "",
|
|
1187
1877
|
taxId: "",
|
|
1188
1878
|
country: ""
|
|
@@ -1229,7 +1919,29 @@ function ElvixLegalEntities({
|
|
|
1229
1919
|
if (result.ok) setRows((prev) => prev?.filter((a) => a.id !== id) ?? null);
|
|
1230
1920
|
onResult?.(result);
|
|
1231
1921
|
}
|
|
1232
|
-
return /* @__PURE__ */
|
|
1922
|
+
return /* @__PURE__ */ jsxs18(ElvixCard, { title: "Legal entities", ...sizeProps, children: [
|
|
1923
|
+
error && /* @__PURE__ */ jsx19("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1924
|
+
!rows && !error && /* @__PURE__ */ jsx19("p", { children: "Loading\u2026" }),
|
|
1925
|
+
rows && rows.length === 0 && /* @__PURE__ */ jsx19("p", { className: "elvix-muted", children: "No legal entities yet." }),
|
|
1926
|
+
rows?.map((e) => /* @__PURE__ */ jsxs18("div", { style: { padding: "8px 0", borderBottom: "1px solid rgba(0,0,0,0.06)", display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1927
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 13 }, children: [
|
|
1928
|
+
/* @__PURE__ */ jsx19("div", { style: { fontWeight: 500 }, children: e.legalName }),
|
|
1929
|
+
/* @__PURE__ */ jsxs18("div", { style: { color: "rgba(0,0,0,0.55)" }, children: [
|
|
1930
|
+
e.taxId,
|
|
1931
|
+
" \xB7 ",
|
|
1932
|
+
e.country
|
|
1933
|
+
] })
|
|
1934
|
+
] }),
|
|
1935
|
+
/* @__PURE__ */ jsx19("button", { type: "button", disabled: busy, onClick: () => remove(e.id), className: "elvix-btn elvix-btn-ghost", children: "Remove" })
|
|
1936
|
+
] }, e.id)),
|
|
1937
|
+
!adding && /* @__PURE__ */ jsx19("button", { type: "button", onClick: () => setAdding(true), className: "elvix-btn elvix-btn-primary", style: { marginTop: 12 }, children: "Add entity" }),
|
|
1938
|
+
adding && /* @__PURE__ */ jsxs18("form", { onSubmit: add, className: "elvix-form", style: { marginTop: 12 }, children: [
|
|
1939
|
+
/* @__PURE__ */ jsx19("input", { value: form.legalName, onChange: (e) => setForm({ ...form, legalName: e.target.value }), placeholder: "Legal name", required: true, className: "elvix-input" }),
|
|
1940
|
+
/* @__PURE__ */ jsx19("input", { value: form.taxId, onChange: (e) => setForm({ ...form, taxId: e.target.value }), placeholder: "Tax / VAT ID", required: true, className: "elvix-input" }),
|
|
1941
|
+
/* @__PURE__ */ jsx19("input", { value: form.country, onChange: (e) => setForm({ ...form, country: e.target.value.toUpperCase() }), placeholder: "Country (ISO-2)", maxLength: 2, required: true, className: "elvix-input" }),
|
|
1942
|
+
/* @__PURE__ */ jsx19("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" })
|
|
1943
|
+
] })
|
|
1944
|
+
] });
|
|
1233
1945
|
}
|
|
1234
1946
|
export {
|
|
1235
1947
|
DEFAULT_COPY,
|
|
@@ -1250,6 +1962,7 @@ export {
|
|
|
1250
1962
|
ElvixSessions,
|
|
1251
1963
|
ElvixSignIn,
|
|
1252
1964
|
ElvixSignInButton,
|
|
1965
|
+
ElvixSignInForm,
|
|
1253
1966
|
ElvixUsername,
|
|
1254
1967
|
getElvixToken,
|
|
1255
1968
|
setElvixToken,
|