@arbidocs/blocks 0.4.146 → 0.4.147
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/agents/index.cjs +262 -262
- package/dist/agents/index.js +5 -5
- package/dist/{chunk-MFMASSEO.cjs → chunk-AINU3EJ6.cjs} +8 -8
- package/dist/{chunk-MFMASSEO.cjs.map → chunk-AINU3EJ6.cjs.map} +1 -1
- package/dist/{chunk-O2GW5IY6.cjs → chunk-AO7SK6WP.cjs} +29 -29
- package/dist/{chunk-O2GW5IY6.cjs.map → chunk-AO7SK6WP.cjs.map} +1 -1
- package/dist/{chunk-OBWYM25Y.js → chunk-DAHCRVPM.js} +3 -3
- package/dist/{chunk-OBWYM25Y.js.map → chunk-DAHCRVPM.js.map} +1 -1
- package/dist/{chunk-FUTMU4FR.js → chunk-DGV7HQA7.js} +6 -179
- package/dist/chunk-DGV7HQA7.js.map +1 -0
- package/dist/{chunk-O6IEZDRC.cjs → chunk-GRGS5M6O.cjs} +181 -3
- package/dist/chunk-GRGS5M6O.cjs.map +1 -0
- package/dist/{chunk-A6IU4GIW.js → chunk-H74HEPKT.js} +3 -3
- package/dist/{chunk-A6IU4GIW.js.map → chunk-H74HEPKT.js.map} +1 -1
- package/dist/{chunk-LPYEUD2D.cjs → chunk-IL3WB3YX.cjs} +3 -3
- package/dist/{chunk-LPYEUD2D.cjs.map → chunk-IL3WB3YX.cjs.map} +1 -1
- package/dist/{chunk-C3CGJK7A.cjs → chunk-LTU35TQN.cjs} +5 -5
- package/dist/{chunk-C3CGJK7A.cjs.map → chunk-LTU35TQN.cjs.map} +1 -1
- package/dist/{chunk-T5B7FM7S.js → chunk-LZRMXJIE.js} +3 -3
- package/dist/{chunk-T5B7FM7S.js.map → chunk-LZRMXJIE.js.map} +1 -1
- package/dist/{chunk-OPTBQSCV.cjs → chunk-MFY2ZNP6.cjs} +2 -181
- package/dist/{chunk-FUTMU4FR.js.map → chunk-MFY2ZNP6.cjs.map} +1 -1
- package/dist/{chunk-6HCJ3ZEU.js → chunk-R6VCPDPF.js} +178 -6
- package/dist/chunk-R6VCPDPF.js.map +1 -0
- package/dist/{chunk-C44TDH54.js → chunk-SUUPR735.js} +3 -3
- package/dist/{chunk-C44TDH54.js.map → chunk-SUUPR735.js.map} +1 -1
- package/dist/{chunk-RB7GX2VT.cjs → chunk-T5I4NRFP.cjs} +6 -6
- package/dist/{chunk-RB7GX2VT.cjs.map → chunk-T5I4NRFP.cjs.map} +1 -1
- package/dist/chunk-U37AYUPI.cjs +5371 -0
- package/dist/chunk-U37AYUPI.cjs.map +1 -0
- package/dist/{chunk-IJST4EBM.js → chunk-VUR63NMQ.js} +5 -5
- package/dist/{chunk-IJST4EBM.js.map → chunk-VUR63NMQ.js.map} +1 -1
- package/dist/chunk-WIZ7Z7FN.js +5179 -0
- package/dist/chunk-WIZ7Z7FN.js.map +1 -0
- package/dist/collaboration/index.cjs +73 -73
- package/dist/collaboration/index.js +2 -2
- package/dist/connect/docx.cjs +7 -7
- package/dist/connect/docx.js +4 -4
- package/dist/connect/index.cjs +1029 -125
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.ts +1 -0
- package/dist/connect/index.js +910 -13
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/connectors/ConnectedAppsSettings.d.ts +24 -0
- package/dist/connection/connectors/ConnectedDriveSyncDialog.d.ts +12 -0
- package/dist/connection/connectors/ConnectedMailboxSyncDialog.d.ts +12 -0
- package/dist/connection/connectors/index.d.ts +4 -0
- package/dist/connection/connectors/sync-labels.d.ts +21 -0
- package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +4 -0
- package/dist/connection/settings-page/index.d.ts +1 -1
- package/dist/files/index.cjs +2 -2
- package/dist/files/index.js +2 -2
- package/dist/index.cjs +395 -395
- package/dist/index.js +11 -11
- package/dist/settings/PlanBadge.d.ts +1 -1
- package/dist/settings/index.cjs +545 -3710
- package/dist/settings/index.cjs.map +1 -1
- package/dist/settings/index.js +8 -3525
- package/dist/settings/index.js.map +1 -1
- package/dist/site/index.cjs +5 -5
- package/dist/site/index.js +1 -1
- package/dist/studio/index.cjs +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/workflow-canvas/index.cjs +18 -18
- package/dist/workflow-canvas/index.js +5 -5
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +4 -4
- package/dist/chunk-5YHEHEJT.js +0 -1667
- package/dist/chunk-5YHEHEJT.js.map +0 -1
- package/dist/chunk-6HCJ3ZEU.js.map +0 -1
- package/dist/chunk-O6IEZDRC.cjs.map +0 -1
- package/dist/chunk-OPTBQSCV.cjs.map +0 -1
- package/dist/chunk-U73KPFYH.cjs +0 -1717
- package/dist/chunk-U73KPFYH.cjs.map +0 -1
package/dist/chunk-5YHEHEJT.js
DELETED
|
@@ -1,1667 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { PasswordStrengthInput } from './chunk-VILAPTCB.js';
|
|
3
|
-
import { TabHeader } from './chunk-4WWM3GQ5.js';
|
|
4
|
-
import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
|
|
5
|
-
import { ModalScaffold, useRestoreFocus } from './chunk-TX2ZICS7.js';
|
|
6
|
-
import { formatCount } from './chunk-OXF2IFXG.js';
|
|
7
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
-
import { useMemo, useRef, useId, useState } from 'react';
|
|
9
|
-
import { Loader2, Camera, ChevronRight, ChevronDown, Check, Pencil, Mail, ShieldCheck, ExternalLink, CheckCircle2, AlertCircle, Radio, AlertTriangle, LogOut, RefreshCw, Wifi, WifiOff, Crown } from 'lucide-react';
|
|
10
|
-
import { Avatar, AvatarImage, AvatarFallback, cn, Input, Button, VerifiedBadge, Tooltip, TooltipTrigger, TooltipContent, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Collapsible, CollapsibleTrigger, CollapsibleContent, Switch, Checkbox, Badge } from '@arbidocs/react/ui';
|
|
11
|
-
|
|
12
|
-
var INTERACTIVE_SELECTOR = 'button, input, select, a, [role="tab"], [role="radio"]';
|
|
13
|
-
function DraggableHeader({ onDragStart, children }) {
|
|
14
|
-
return /* @__PURE__ */ jsx(
|
|
15
|
-
"div",
|
|
16
|
-
{
|
|
17
|
-
className: "flex-shrink-0",
|
|
18
|
-
onMouseDown: onDragStart ? (e) => {
|
|
19
|
-
const target = e.target;
|
|
20
|
-
if (target.closest(INTERACTIVE_SELECTOR)) return;
|
|
21
|
-
onDragStart(e);
|
|
22
|
-
} : void 0,
|
|
23
|
-
style: onDragStart ? { cursor: "move" } : void 0,
|
|
24
|
-
children
|
|
25
|
-
}
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
var DEFAULT_AVATAR_PICKER_LABELS = {
|
|
29
|
-
uploadingPicture: "Uploading picture",
|
|
30
|
-
changeProfilePicture: "Change profile picture",
|
|
31
|
-
change: "Change"
|
|
32
|
-
};
|
|
33
|
-
function AvatarPicker({
|
|
34
|
-
pictureUrl,
|
|
35
|
-
initials,
|
|
36
|
-
fallbackClassName,
|
|
37
|
-
isUploading,
|
|
38
|
-
disabled,
|
|
39
|
-
onFileChosen,
|
|
40
|
-
testId = "avatar-uploader-input",
|
|
41
|
-
labels
|
|
42
|
-
}) {
|
|
43
|
-
const l = useMemo(() => ({ ...DEFAULT_AVATAR_PICKER_LABELS, ...labels }), [labels]);
|
|
44
|
-
const fileInputRef = useRef(null);
|
|
45
|
-
const handleChange = (e) => {
|
|
46
|
-
const file = e.target.files?.[0];
|
|
47
|
-
e.target.value = "";
|
|
48
|
-
if (file) onFileChosen(file);
|
|
49
|
-
};
|
|
50
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "avatar-picker", className: "group/avatar relative shrink-0", children: [
|
|
51
|
-
/* @__PURE__ */ jsxs(Avatar, { className: "h-20 w-20 ring-1 ring-border", children: [
|
|
52
|
-
pictureUrl && /* @__PURE__ */ jsx(AvatarImage, { src: pictureUrl, alt: initials }),
|
|
53
|
-
/* @__PURE__ */ jsx(
|
|
54
|
-
AvatarFallback,
|
|
55
|
-
{
|
|
56
|
-
className: cn("text-2xl font-semibold leading-none text-white", fallbackClassName),
|
|
57
|
-
children: initials
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
] }),
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
62
|
-
"button",
|
|
63
|
-
{
|
|
64
|
-
type: "button",
|
|
65
|
-
onClick: () => fileInputRef.current?.click(),
|
|
66
|
-
disabled: disabled || isUploading,
|
|
67
|
-
className: cn(
|
|
68
|
-
"absolute inset-0 flex items-center justify-center rounded-full",
|
|
69
|
-
"bg-foreground/70 text-background",
|
|
70
|
-
"opacity-0 focus-visible:opacity-100 group-hover/avatar:opacity-100",
|
|
71
|
-
// Touch has no hover: keep the change affordance visible (lighter scrim over the photo).
|
|
72
|
-
"pointer-coarse:opacity-100",
|
|
73
|
-
"transition-opacity duration-200",
|
|
74
|
-
"disabled:cursor-not-allowed disabled:opacity-100"
|
|
75
|
-
),
|
|
76
|
-
"aria-label": isUploading ? l.uploadingPicture : l.changeProfilePicture,
|
|
77
|
-
children: isUploading ? /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin" }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
78
|
-
/* @__PURE__ */ jsx(Camera, { className: "h-5 w-5" }),
|
|
79
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: l.change })
|
|
80
|
-
] })
|
|
81
|
-
}
|
|
82
|
-
),
|
|
83
|
-
/* @__PURE__ */ jsx(
|
|
84
|
-
"span",
|
|
85
|
-
{
|
|
86
|
-
"aria-hidden": "true",
|
|
87
|
-
className: "pointer-events-none absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-background text-muted-foreground ring-1 ring-border",
|
|
88
|
-
children: /* @__PURE__ */ jsx(Camera, { className: "h-3.5 w-3.5" })
|
|
89
|
-
}
|
|
90
|
-
),
|
|
91
|
-
/* @__PURE__ */ jsx(
|
|
92
|
-
"input",
|
|
93
|
-
{
|
|
94
|
-
ref: fileInputRef,
|
|
95
|
-
type: "file",
|
|
96
|
-
accept: "image/png,image/jpeg,image/webp,image/gif",
|
|
97
|
-
onChange: handleChange,
|
|
98
|
-
hidden: true,
|
|
99
|
-
className: "hidden",
|
|
100
|
-
"data-testid": testId
|
|
101
|
-
}
|
|
102
|
-
)
|
|
103
|
-
] });
|
|
104
|
-
}
|
|
105
|
-
var DEFAULT_SETTINGS_DANGER_ZONE_LABELS = {
|
|
106
|
-
dangerZone: "Danger Zone"
|
|
107
|
-
};
|
|
108
|
-
function SettingsPanel({ className, testId, ...props }) {
|
|
109
|
-
return /* @__PURE__ */ jsx(
|
|
110
|
-
"div",
|
|
111
|
-
{
|
|
112
|
-
"data-slot": "settings-panel",
|
|
113
|
-
"data-testid": testId,
|
|
114
|
-
className: cn("mx-auto w-full max-w-xl space-y-6", className),
|
|
115
|
-
...props
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
function SettingsSection({
|
|
120
|
-
icon,
|
|
121
|
-
title,
|
|
122
|
-
description,
|
|
123
|
-
action,
|
|
124
|
-
testId,
|
|
125
|
-
className,
|
|
126
|
-
children,
|
|
127
|
-
...props
|
|
128
|
-
}) {
|
|
129
|
-
return /* @__PURE__ */ jsxs(
|
|
130
|
-
"section",
|
|
131
|
-
{
|
|
132
|
-
"data-slot": "settings-section",
|
|
133
|
-
"data-testid": testId,
|
|
134
|
-
className: cn("space-y-3", className),
|
|
135
|
-
...props,
|
|
136
|
-
children: [
|
|
137
|
-
(title || action) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
138
|
-
title && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
139
|
-
icon && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground [&_svg]:h-4 [&_svg]:w-4", children: icon }),
|
|
140
|
-
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-foreground", children: title })
|
|
141
|
-
] }),
|
|
142
|
-
action
|
|
143
|
-
] }),
|
|
144
|
-
description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }),
|
|
145
|
-
children
|
|
146
|
-
]
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
function SettingsRow({
|
|
151
|
-
label,
|
|
152
|
-
labelFor,
|
|
153
|
-
description,
|
|
154
|
-
children,
|
|
155
|
-
testId,
|
|
156
|
-
className,
|
|
157
|
-
...props
|
|
158
|
-
}) {
|
|
159
|
-
return /* @__PURE__ */ jsxs(
|
|
160
|
-
"div",
|
|
161
|
-
{
|
|
162
|
-
"data-slot": "settings-row",
|
|
163
|
-
"data-testid": testId,
|
|
164
|
-
className: cn(
|
|
165
|
-
"flex flex-col gap-2 py-2 @xl:flex-row @xl:items-center @xl:justify-between @xl:gap-6",
|
|
166
|
-
className
|
|
167
|
-
),
|
|
168
|
-
...props,
|
|
169
|
-
children: [
|
|
170
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
171
|
-
labelFor ? /* @__PURE__ */ jsx("label", { htmlFor: labelFor, className: "text-sm font-medium text-foreground", children: label }) : /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-foreground", children: label }),
|
|
172
|
-
description && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: description })
|
|
173
|
-
] }),
|
|
174
|
-
children && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children })
|
|
175
|
-
]
|
|
176
|
-
}
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
function SettingsCard({ padding = "md", className, ...props }) {
|
|
180
|
-
return /* @__PURE__ */ jsx(
|
|
181
|
-
"div",
|
|
182
|
-
{
|
|
183
|
-
"data-slot": "settings-card",
|
|
184
|
-
className: cn(
|
|
185
|
-
"rounded-lg border border-border bg-card shadow-xs",
|
|
186
|
-
padding === "md" ? "space-y-5 p-5" : "divide-y divide-border p-2",
|
|
187
|
-
className
|
|
188
|
-
),
|
|
189
|
-
...props
|
|
190
|
-
}
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
function SettingsActionRow({ title, description, onClick, testId }) {
|
|
194
|
-
return /* @__PURE__ */ jsxs(
|
|
195
|
-
"button",
|
|
196
|
-
{
|
|
197
|
-
type: "button",
|
|
198
|
-
onClick,
|
|
199
|
-
"data-slot": "settings-action-row",
|
|
200
|
-
"data-testid": testId,
|
|
201
|
-
className: "flex w-full items-center gap-3 rounded-md px-3 py-3 text-left transition-colors hover:bg-background/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
|
|
202
|
-
children: [
|
|
203
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
204
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
205
|
-
description && /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs leading-relaxed text-muted-foreground", children: description })
|
|
206
|
-
] }),
|
|
207
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
|
|
208
|
-
]
|
|
209
|
-
}
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
function SettingsDangerZone({
|
|
213
|
-
isOpen,
|
|
214
|
-
onToggle,
|
|
215
|
-
label,
|
|
216
|
-
title,
|
|
217
|
-
description,
|
|
218
|
-
action,
|
|
219
|
-
labels
|
|
220
|
-
}) {
|
|
221
|
-
const l = useMemo(() => ({ ...DEFAULT_SETTINGS_DANGER_ZONE_LABELS, ...labels }), [labels]);
|
|
222
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "settings-danger-zone", className: "mt-8 pt-2", children: [
|
|
223
|
-
/* @__PURE__ */ jsxs(
|
|
224
|
-
"button",
|
|
225
|
-
{
|
|
226
|
-
type: "button",
|
|
227
|
-
onClick: onToggle,
|
|
228
|
-
"aria-expanded": isOpen,
|
|
229
|
-
className: "flex w-full items-center gap-1.5 text-left pointer-coarse:min-h-11",
|
|
230
|
-
children: [
|
|
231
|
-
isOpen ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
232
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground", children: label ?? l.dangerZone })
|
|
233
|
-
]
|
|
234
|
-
}
|
|
235
|
-
),
|
|
236
|
-
isOpen && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between gap-4 rounded-lg bg-destructive/5 p-4", children: [
|
|
237
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
238
|
-
/* @__PURE__ */ jsx("p", { className: "font-medium", children: title }),
|
|
239
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
240
|
-
] }),
|
|
241
|
-
/* @__PURE__ */ jsx("div", { className: "shrink-0", children: action })
|
|
242
|
-
] })
|
|
243
|
-
] });
|
|
244
|
-
}
|
|
245
|
-
var DEFAULT_PROFILE_CARD_LABELS = {
|
|
246
|
-
firstName: "First name",
|
|
247
|
-
lastName: "Last name",
|
|
248
|
-
save: "Save",
|
|
249
|
-
cancel: "Cancel",
|
|
250
|
-
sso: "SSO",
|
|
251
|
-
ssoTooltip: "Your email is managed by your sign-in provider. Change it there and it will sync here automatically on your next sign-in.",
|
|
252
|
-
change: "Change",
|
|
253
|
-
newEmailAddress: "New email address",
|
|
254
|
-
emailPlaceholder: "you@example.com",
|
|
255
|
-
codeWillBeSent: "We\u2019ll send a 3-word verification code to this address.",
|
|
256
|
-
sendCode: "Send code",
|
|
257
|
-
verify: (email) => `Verify ${email}`,
|
|
258
|
-
codePlaceholder: "WORD-WORD-WORD",
|
|
259
|
-
enterCodeHint: "Enter the 3-word code from the email we just sent.",
|
|
260
|
-
confirm: "Confirm",
|
|
261
|
-
resendIn: (seconds) => `Resend in ${seconds}s`,
|
|
262
|
-
resendCode: "Resend code",
|
|
263
|
-
verifiedNameLocked: "Verified name. Remove your identity verification to change it."
|
|
264
|
-
};
|
|
265
|
-
function ProfileCard({
|
|
266
|
-
avatar,
|
|
267
|
-
name,
|
|
268
|
-
email,
|
|
269
|
-
isSso,
|
|
270
|
-
isVerified = false,
|
|
271
|
-
onStartEmailChange,
|
|
272
|
-
emailChange,
|
|
273
|
-
ssoTooltip,
|
|
274
|
-
labels
|
|
275
|
-
}) {
|
|
276
|
-
const l = useMemo(() => ({ ...DEFAULT_PROFILE_CARD_LABELS, ...labels }), [labels]);
|
|
277
|
-
return /* @__PURE__ */ jsxs(SettingsCard, { children: [
|
|
278
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-5", children: [
|
|
279
|
-
avatar,
|
|
280
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [
|
|
281
|
-
name.isEditing ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
282
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 @xl:flex-row", children: [
|
|
283
|
-
/* @__PURE__ */ jsx(
|
|
284
|
-
Input,
|
|
285
|
-
{
|
|
286
|
-
value: name.givenName,
|
|
287
|
-
onChange: (e) => name.onGivenNameChange(e.target.value),
|
|
288
|
-
placeholder: l.firstName,
|
|
289
|
-
className: "flex-1",
|
|
290
|
-
autoFocus: true
|
|
291
|
-
}
|
|
292
|
-
),
|
|
293
|
-
/* @__PURE__ */ jsx(
|
|
294
|
-
Input,
|
|
295
|
-
{
|
|
296
|
-
value: name.familyName,
|
|
297
|
-
onChange: (e) => name.onFamilyNameChange(e.target.value),
|
|
298
|
-
placeholder: l.lastName,
|
|
299
|
-
className: "flex-1"
|
|
300
|
-
}
|
|
301
|
-
)
|
|
302
|
-
] }),
|
|
303
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
304
|
-
/* @__PURE__ */ jsxs(
|
|
305
|
-
Button,
|
|
306
|
-
{
|
|
307
|
-
onClick: name.onSave,
|
|
308
|
-
size: "sm",
|
|
309
|
-
disabled: !name.givenName.trim() || name.isSaving,
|
|
310
|
-
children: [
|
|
311
|
-
name.isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Check, { className: "mr-1 h-4 w-4" }),
|
|
312
|
-
l.save
|
|
313
|
-
]
|
|
314
|
-
}
|
|
315
|
-
),
|
|
316
|
-
/* @__PURE__ */ jsx(Button, { onClick: name.onCancel, size: "sm", variant: "ghost", disabled: name.isSaving, children: l.cancel })
|
|
317
|
-
] })
|
|
318
|
-
] }) : isVerified ? /* @__PURE__ */ jsxs("div", { className: "-mx-2 w-full px-2 py-1", "data-testid": "verified-name", children: [
|
|
319
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
320
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-heading text-xl font-semibold text-foreground", children: name.display }),
|
|
321
|
-
/* @__PURE__ */ jsx(VerifiedBadge, { className: "h-4 w-4" })
|
|
322
|
-
] }),
|
|
323
|
-
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: l.verifiedNameLocked })
|
|
324
|
-
] }) : /* @__PURE__ */ jsx(
|
|
325
|
-
"button",
|
|
326
|
-
{
|
|
327
|
-
type: "button",
|
|
328
|
-
onClick: name.onStartEdit,
|
|
329
|
-
className: "-mx-2 w-full rounded-md px-2 py-1 text-left transition-colors hover:bg-background/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
|
|
330
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
331
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-heading text-xl font-semibold text-foreground", children: name.display }),
|
|
332
|
-
/* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
|
|
333
|
-
] })
|
|
334
|
-
}
|
|
335
|
-
),
|
|
336
|
-
!emailChange && /* @__PURE__ */ jsxs("div", { className: "-mx-2 flex min-w-0 items-center gap-2 px-2 py-1", children: [
|
|
337
|
-
/* @__PURE__ */ jsx(Mail, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
338
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm text-muted-foreground", children: email }),
|
|
339
|
-
isSso ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
340
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
341
|
-
"span",
|
|
342
|
-
{
|
|
343
|
-
className: "ml-1 shrink-0 cursor-help rounded bg-background px-1.5 py-0.5 text-xs font-medium text-muted-foreground",
|
|
344
|
-
tabIndex: 0,
|
|
345
|
-
children: l.sso
|
|
346
|
-
}
|
|
347
|
-
) }),
|
|
348
|
-
/* @__PURE__ */ jsx(TooltipContent, { className: "max-w-xs", children: ssoTooltip ?? l.ssoTooltip })
|
|
349
|
-
] }) : /* @__PURE__ */ jsx(
|
|
350
|
-
"button",
|
|
351
|
-
{
|
|
352
|
-
type: "button",
|
|
353
|
-
onClick: onStartEmailChange,
|
|
354
|
-
className: "ml-auto shrink-0 text-xs font-medium text-primary hover:underline pointer-coarse:min-h-11",
|
|
355
|
-
children: l.change
|
|
356
|
-
}
|
|
357
|
-
)
|
|
358
|
-
] })
|
|
359
|
-
] })
|
|
360
|
-
] }),
|
|
361
|
-
emailChange && !isSso && /* @__PURE__ */ jsx("div", { className: "animate-accordion-down overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "space-y-3 rounded-lg bg-background p-4", children: emailChange.step === "enter" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
362
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-muted-foreground", children: [
|
|
363
|
-
/* @__PURE__ */ jsx(Mail, { className: "h-3.5 w-3.5" }),
|
|
364
|
-
l.newEmailAddress
|
|
365
|
-
] }),
|
|
366
|
-
/* @__PURE__ */ jsx(
|
|
367
|
-
Input,
|
|
368
|
-
{
|
|
369
|
-
type: "email",
|
|
370
|
-
value: emailChange.newEmail,
|
|
371
|
-
onChange: (e) => emailChange.onNewEmailChange(e.target.value),
|
|
372
|
-
placeholder: l.emailPlaceholder,
|
|
373
|
-
autoFocus: true
|
|
374
|
-
}
|
|
375
|
-
),
|
|
376
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: l.codeWillBeSent }),
|
|
377
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-1", children: [
|
|
378
|
-
/* @__PURE__ */ jsxs(
|
|
379
|
-
Button,
|
|
380
|
-
{
|
|
381
|
-
onClick: emailChange.onSendCode,
|
|
382
|
-
size: "sm",
|
|
383
|
-
disabled: !emailChange.newEmail.trim() || emailChange.isSending,
|
|
384
|
-
children: [
|
|
385
|
-
emailChange.isSending ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Mail, { className: "mr-1 h-4 w-4" }),
|
|
386
|
-
l.sendCode
|
|
387
|
-
]
|
|
388
|
-
}
|
|
389
|
-
),
|
|
390
|
-
/* @__PURE__ */ jsx(
|
|
391
|
-
Button,
|
|
392
|
-
{
|
|
393
|
-
onClick: emailChange.onCancel,
|
|
394
|
-
size: "sm",
|
|
395
|
-
variant: "ghost",
|
|
396
|
-
disabled: emailChange.isSending,
|
|
397
|
-
children: l.cancel
|
|
398
|
-
}
|
|
399
|
-
)
|
|
400
|
-
] })
|
|
401
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
402
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-muted-foreground", children: [
|
|
403
|
-
/* @__PURE__ */ jsx(Mail, { className: "h-3.5 w-3.5" }),
|
|
404
|
-
l.verify(emailChange.newEmail)
|
|
405
|
-
] }),
|
|
406
|
-
/* @__PURE__ */ jsx(
|
|
407
|
-
Input,
|
|
408
|
-
{
|
|
409
|
-
value: emailChange.code,
|
|
410
|
-
onChange: (e) => emailChange.onCodeChange(e.target.value.toUpperCase().replace(/\s+/g, "-")),
|
|
411
|
-
className: cn("text-center font-mono tracking-wider"),
|
|
412
|
-
placeholder: l.codePlaceholder,
|
|
413
|
-
autoFocus: true
|
|
414
|
-
}
|
|
415
|
-
),
|
|
416
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: l.enterCodeHint }),
|
|
417
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 pt-1", children: [
|
|
418
|
-
/* @__PURE__ */ jsxs(
|
|
419
|
-
Button,
|
|
420
|
-
{
|
|
421
|
-
onClick: emailChange.onConfirm,
|
|
422
|
-
size: "sm",
|
|
423
|
-
disabled: !emailChange.code.trim() || emailChange.isConfirming,
|
|
424
|
-
children: [
|
|
425
|
-
emailChange.isConfirming ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Check, { className: "mr-1 h-4 w-4" }),
|
|
426
|
-
l.confirm
|
|
427
|
-
]
|
|
428
|
-
}
|
|
429
|
-
),
|
|
430
|
-
/* @__PURE__ */ jsx(
|
|
431
|
-
Button,
|
|
432
|
-
{
|
|
433
|
-
onClick: () => {
|
|
434
|
-
if (emailChange.cooldownSeconds > 0) return;
|
|
435
|
-
emailChange.onSendCode();
|
|
436
|
-
},
|
|
437
|
-
size: "sm",
|
|
438
|
-
variant: "ghost",
|
|
439
|
-
disabled: emailChange.cooldownSeconds > 0 || emailChange.isSending,
|
|
440
|
-
children: emailChange.cooldownSeconds > 0 ? l.resendIn(emailChange.cooldownSeconds) : l.resendCode
|
|
441
|
-
}
|
|
442
|
-
),
|
|
443
|
-
/* @__PURE__ */ jsx(
|
|
444
|
-
Button,
|
|
445
|
-
{
|
|
446
|
-
onClick: emailChange.onCancel,
|
|
447
|
-
size: "sm",
|
|
448
|
-
variant: "ghost",
|
|
449
|
-
disabled: emailChange.isConfirming,
|
|
450
|
-
children: l.cancel
|
|
451
|
-
}
|
|
452
|
-
)
|
|
453
|
-
] })
|
|
454
|
-
] }) }) })
|
|
455
|
-
] });
|
|
456
|
-
}
|
|
457
|
-
var DEFAULT_IDENTITY_VERIFICATION_LABELS = {
|
|
458
|
-
title: "Identity verification",
|
|
459
|
-
intro: "Check your ID once to get a verified tick next to your name.",
|
|
460
|
-
priceLine: (price, attempts) => `${price} \xB7 ${attempts} attempts`,
|
|
461
|
-
proOnly: "Available on Pro plans.",
|
|
462
|
-
seePlans: "See plans",
|
|
463
|
-
manageBilling: "Manage billing",
|
|
464
|
-
verify: "Verify identity",
|
|
465
|
-
continue: "Continue",
|
|
466
|
-
attemptsLeft: (n) => `${n} attempt${n === 1 ? "" : "s"} left`,
|
|
467
|
-
verified: "Verified",
|
|
468
|
-
verifiedDetail: (country) => `ID issued in ${country}`,
|
|
469
|
-
inReview: "Your check is being reviewed. We\u2019ll update this when it\u2019s done.",
|
|
470
|
-
finishName: "Your ID was verified. Confirm your name to get the tick.",
|
|
471
|
-
finish: "Finish",
|
|
472
|
-
remove: "Remove",
|
|
473
|
-
payTitle: "Verify your identity",
|
|
474
|
-
payBody: (price, attempts) => `A one-time fee of ${price} is charged to the card on your Pro plan. It covers up to ${attempts} attempts. Your ID is checked by our provider, Didit; ARBI does not keep your document.`,
|
|
475
|
-
pay: "Pay and continue",
|
|
476
|
-
confirmPayment: "Confirm payment with your bank",
|
|
477
|
-
paymentConfirmed: "I\u2019ve confirmed it",
|
|
478
|
-
verifyTitle: "Scan your ID",
|
|
479
|
-
embedFailed: "Your camera isn\u2019t available here. Continue in a new tab, then come back.",
|
|
480
|
-
openInNewTab: "Open in a new tab",
|
|
481
|
-
checkResult: "I\u2019ve finished",
|
|
482
|
-
resultVerified: "You\u2019re verified. The tick now shows next to your name.",
|
|
483
|
-
resultDeclined: (n) => n > 0 ? `We couldn\u2019t verify your ID. You have ${n} attempt${n === 1 ? "" : "s"} left.` : "We couldn\u2019t verify your ID and no attempts are left.",
|
|
484
|
-
tryAgain: "Try again",
|
|
485
|
-
resultInReview: "Your check needs a manual review. We\u2019ll show the result here when it\u2019s done.",
|
|
486
|
-
nameMismatchTitle: "Your ID was verified",
|
|
487
|
-
nameMismatchBody: "The name on your ID differs from your account name. The tick shows only with the name on your ID.",
|
|
488
|
-
documentName: "Name on your ID",
|
|
489
|
-
accountName: "Account name",
|
|
490
|
-
useDocumentName: (name) => `Change my name to ${name}`,
|
|
491
|
-
keepName: "Keep my name",
|
|
492
|
-
close: "Close",
|
|
493
|
-
requiredTitle: "Identity verification required",
|
|
494
|
-
requiredBody: "This workspace requires a verified identity before you continue.",
|
|
495
|
-
requiredProOnly: "Identity verification is available on Pro plans. Ask your administrator."
|
|
496
|
-
};
|
|
497
|
-
function useLabels(labels) {
|
|
498
|
-
return useMemo(() => ({ ...DEFAULT_IDENTITY_VERIFICATION_LABELS, ...labels }), [labels]);
|
|
499
|
-
}
|
|
500
|
-
var BILLING_CODES = [
|
|
501
|
-
"PRO_REQUIRED",
|
|
502
|
-
"PAYMENT_METHOD_REQUIRED",
|
|
503
|
-
"BILLING_ADDRESS_REQUIRED",
|
|
504
|
-
"PAYMENT_DECLINED"
|
|
505
|
-
];
|
|
506
|
-
function Problem({
|
|
507
|
-
flow,
|
|
508
|
-
onManageBilling,
|
|
509
|
-
label
|
|
510
|
-
}) {
|
|
511
|
-
if (!flow.problem) return null;
|
|
512
|
-
const billing = onManageBilling && BILLING_CODES.includes(flow.problem.code ?? "");
|
|
513
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", "data-testid": "identity-problem", children: [
|
|
514
|
-
/* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: flow.problem.message }),
|
|
515
|
-
billing && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", onClick: onManageBilling, children: label })
|
|
516
|
-
] });
|
|
517
|
-
}
|
|
518
|
-
function IdentityVerificationCard({
|
|
519
|
-
flow,
|
|
520
|
-
onManageBilling,
|
|
521
|
-
labels
|
|
522
|
-
}) {
|
|
523
|
-
const l = useLabels(labels);
|
|
524
|
-
const { status } = flow;
|
|
525
|
-
if (!status?.enabled) return null;
|
|
526
|
-
const busy = flow.busy !== null;
|
|
527
|
-
let description;
|
|
528
|
-
let action = null;
|
|
529
|
-
if (status.verified) {
|
|
530
|
-
description = /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
531
|
-
/* @__PURE__ */ jsx(VerifiedBadge, {}),
|
|
532
|
-
l.verified,
|
|
533
|
-
status.document_country && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
534
|
-
" \xB7 ",
|
|
535
|
-
l.verifiedDetail(status.document_country)
|
|
536
|
-
] })
|
|
537
|
-
] });
|
|
538
|
-
action = /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: flow.remove, disabled: busy, children: l.remove });
|
|
539
|
-
} else if (!status.eligible) {
|
|
540
|
-
description = `${l.intro} ${l.proOnly}`;
|
|
541
|
-
action = onManageBilling ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", onClick: onManageBilling, children: l.seePlans }) : null;
|
|
542
|
-
} else if (status.state === "in_review") {
|
|
543
|
-
description = l.inReview;
|
|
544
|
-
} else if (status.state === "name_mismatch") {
|
|
545
|
-
description = l.finishName;
|
|
546
|
-
action = /* @__PURE__ */ jsx(Button, { size: "sm", onClick: flow.open, children: l.finish });
|
|
547
|
-
} else {
|
|
548
|
-
const resuming = status.attempts_left > 0 || status.state === "in_progress";
|
|
549
|
-
description = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
550
|
-
l.intro,
|
|
551
|
-
" ",
|
|
552
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: resuming ? l.attemptsLeft(status.attempts_left) : l.priceLine(flow.price ?? "", status.attempts_per_fee) })
|
|
553
|
-
] });
|
|
554
|
-
action = /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: flow.open, disabled: busy, children: [
|
|
555
|
-
/* @__PURE__ */ jsx(ShieldCheck, { className: "mr-1 h-4 w-4" }),
|
|
556
|
-
resuming ? l.continue : l.verify
|
|
557
|
-
] });
|
|
558
|
-
}
|
|
559
|
-
return /* @__PURE__ */ jsxs(SettingsCard, { padding: "sm", "data-testid": "identity-verification-card", children: [
|
|
560
|
-
/* @__PURE__ */ jsx(SettingsRow, { label: l.title, description, children: action }),
|
|
561
|
-
!flow.isOpen && /* @__PURE__ */ jsx(Problem, { flow, onManageBilling, label: l.manageBilling })
|
|
562
|
-
] });
|
|
563
|
-
}
|
|
564
|
-
function IdentityVerificationDialog({
|
|
565
|
-
flow,
|
|
566
|
-
accountName,
|
|
567
|
-
dismissible = true,
|
|
568
|
-
onManageBilling,
|
|
569
|
-
labels
|
|
570
|
-
}) {
|
|
571
|
-
const l = useLabels(labels);
|
|
572
|
-
const { status } = flow;
|
|
573
|
-
const attempts = status?.attempts_per_fee ?? 0;
|
|
574
|
-
const docName = [status?.document_given_name, status?.document_family_name].filter(Boolean).join(" ");
|
|
575
|
-
const spinner = /* @__PURE__ */ jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" });
|
|
576
|
-
let body;
|
|
577
|
-
let footer = null;
|
|
578
|
-
if (flow.step === "pay") {
|
|
579
|
-
body = flow.paymentUrl ? /* @__PURE__ */ jsxs(
|
|
580
|
-
"a",
|
|
581
|
-
{
|
|
582
|
-
href: flow.paymentUrl,
|
|
583
|
-
target: "_blank",
|
|
584
|
-
rel: "noopener noreferrer",
|
|
585
|
-
className: "inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline",
|
|
586
|
-
children: [
|
|
587
|
-
l.confirmPayment,
|
|
588
|
-
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5" })
|
|
589
|
-
]
|
|
590
|
-
}
|
|
591
|
-
) : /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.payBody(flow.price ?? "", attempts) });
|
|
592
|
-
footer = flow.paymentUrl ? /* @__PURE__ */ jsxs(Button, { onClick: flow.recheckPayment, disabled: flow.busy !== null, children: [
|
|
593
|
-
flow.busy === "start" && spinner,
|
|
594
|
-
l.paymentConfirmed
|
|
595
|
-
] }) : /* @__PURE__ */ jsxs(Button, { onClick: flow.pay, disabled: flow.busy !== null, "data-testid": "identity-pay", children: [
|
|
596
|
-
flow.busy === "pay" && spinner,
|
|
597
|
-
l.pay
|
|
598
|
-
] });
|
|
599
|
-
} else if (flow.step === "verify") {
|
|
600
|
-
body = /* @__PURE__ */ jsx("div", { className: "space-y-3", children: flow.embedFailed ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.embedFailed }) : /* @__PURE__ */ jsx(
|
|
601
|
-
"div",
|
|
602
|
-
{
|
|
603
|
-
id: flow.verifyContainerId,
|
|
604
|
-
ref: flow.verifyContainerRef,
|
|
605
|
-
className: "h-[560px] w-full overflow-hidden rounded-md bg-muted",
|
|
606
|
-
"data-testid": "identity-didit-frame",
|
|
607
|
-
children: flow.busy === "start" && /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) })
|
|
608
|
-
}
|
|
609
|
-
) });
|
|
610
|
-
footer = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
611
|
-
flow.embedFailed && /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: flow.openInNewTab, children: [
|
|
612
|
-
/* @__PURE__ */ jsx(ExternalLink, { className: "mr-1 h-4 w-4" }),
|
|
613
|
-
l.openInNewTab
|
|
614
|
-
] }),
|
|
615
|
-
/* @__PURE__ */ jsxs(Button, { variant: "ghost", onClick: flow.checkResult, disabled: flow.busy !== null, children: [
|
|
616
|
-
flow.busy === "refresh" && spinner,
|
|
617
|
-
l.checkResult
|
|
618
|
-
] })
|
|
619
|
-
] });
|
|
620
|
-
} else if (status?.state === "name_mismatch") {
|
|
621
|
-
body = /* @__PURE__ */ jsxs("div", { className: "space-y-3", "data-testid": "identity-name-mismatch", children: [
|
|
622
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.nameMismatchBody }),
|
|
623
|
-
/* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-sm", children: [
|
|
624
|
-
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: l.documentName }),
|
|
625
|
-
/* @__PURE__ */ jsx("dd", { className: "font-medium", children: docName }),
|
|
626
|
-
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: l.accountName }),
|
|
627
|
-
/* @__PURE__ */ jsx("dd", { children: accountName })
|
|
628
|
-
] })
|
|
629
|
-
] });
|
|
630
|
-
footer = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
631
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: flow.keepName, disabled: flow.busy !== null, children: l.keepName }),
|
|
632
|
-
/* @__PURE__ */ jsxs(Button, { onClick: flow.acceptName, disabled: flow.busy !== null || !docName, children: [
|
|
633
|
-
flow.busy === "accept" && spinner,
|
|
634
|
-
l.useDocumentName(docName)
|
|
635
|
-
] })
|
|
636
|
-
] });
|
|
637
|
-
} else if (status?.verified) {
|
|
638
|
-
body = /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm", children: [
|
|
639
|
-
/* @__PURE__ */ jsx(VerifiedBadge, { className: "h-4 w-4" }),
|
|
640
|
-
l.resultVerified
|
|
641
|
-
] });
|
|
642
|
-
footer = /* @__PURE__ */ jsx(Button, { onClick: flow.close, children: l.close });
|
|
643
|
-
} else if (status?.state === "in_review") {
|
|
644
|
-
body = /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.resultInReview });
|
|
645
|
-
footer = /* @__PURE__ */ jsx(Button, { onClick: flow.close, children: l.close });
|
|
646
|
-
} else {
|
|
647
|
-
const left = status?.attempts_left ?? 0;
|
|
648
|
-
body = /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.resultDeclined(left) });
|
|
649
|
-
footer = left > 0 ? /* @__PURE__ */ jsx(Button, { onClick: flow.retry, disabled: flow.busy !== null, children: l.tryAgain }) : /* @__PURE__ */ jsx(Button, { onClick: flow.close, children: l.close });
|
|
650
|
-
}
|
|
651
|
-
const title = status?.state === "name_mismatch" && flow.step === "result" ? l.nameMismatchTitle : flow.step === "verify" ? l.verifyTitle : l.payTitle;
|
|
652
|
-
return /* @__PURE__ */ jsxs(
|
|
653
|
-
ModalScaffold,
|
|
654
|
-
{
|
|
655
|
-
open: flow.isOpen,
|
|
656
|
-
onOpenChange: (open) => open ? flow.open() : flow.close(),
|
|
657
|
-
title,
|
|
658
|
-
icon: /* @__PURE__ */ jsx(ShieldCheck, { className: "h-5 w-5" }),
|
|
659
|
-
size: flow.step === "verify" ? "lg" : "md",
|
|
660
|
-
dismissible,
|
|
661
|
-
testId: "identity-verification-dialog",
|
|
662
|
-
children: [
|
|
663
|
-
/* @__PURE__ */ jsxs(ModalScaffold.Body, { children: [
|
|
664
|
-
body,
|
|
665
|
-
/* @__PURE__ */ jsx(Problem, { flow, onManageBilling, label: l.manageBilling })
|
|
666
|
-
] }),
|
|
667
|
-
/* @__PURE__ */ jsx(ModalScaffold.Footer, { children: footer })
|
|
668
|
-
]
|
|
669
|
-
}
|
|
670
|
-
);
|
|
671
|
-
}
|
|
672
|
-
function RequireVerified({
|
|
673
|
-
flow,
|
|
674
|
-
accountName,
|
|
675
|
-
onManageBilling,
|
|
676
|
-
children,
|
|
677
|
-
labels
|
|
678
|
-
}) {
|
|
679
|
-
const l = useLabels(labels);
|
|
680
|
-
const { status } = flow;
|
|
681
|
-
const blocked = Boolean(status?.enabled && status.required && !status.verified);
|
|
682
|
-
if (!blocked || !status) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
683
|
-
if (flow.isOpen) {
|
|
684
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
685
|
-
children,
|
|
686
|
-
/* @__PURE__ */ jsx(
|
|
687
|
-
IdentityVerificationDialog,
|
|
688
|
-
{
|
|
689
|
-
flow,
|
|
690
|
-
accountName,
|
|
691
|
-
dismissible: false,
|
|
692
|
-
onManageBilling,
|
|
693
|
-
labels
|
|
694
|
-
}
|
|
695
|
-
)
|
|
696
|
-
] });
|
|
697
|
-
}
|
|
698
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
699
|
-
children,
|
|
700
|
-
/* @__PURE__ */ jsxs(
|
|
701
|
-
ModalScaffold,
|
|
702
|
-
{
|
|
703
|
-
open: true,
|
|
704
|
-
onOpenChange: () => {
|
|
705
|
-
},
|
|
706
|
-
title: l.requiredTitle,
|
|
707
|
-
icon: /* @__PURE__ */ jsx(ShieldCheck, { className: "h-5 w-5" }),
|
|
708
|
-
dismissible: false,
|
|
709
|
-
testId: "identity-required-gate",
|
|
710
|
-
children: [
|
|
711
|
-
/* @__PURE__ */ jsx(ModalScaffold.Body, { children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: status.eligible ? l.requiredBody : l.requiredProOnly }) }),
|
|
712
|
-
status.eligible && /* @__PURE__ */ jsx(ModalScaffold.Footer, { children: /* @__PURE__ */ jsx(Button, { onClick: flow.open, children: l.verify }) })
|
|
713
|
-
]
|
|
714
|
-
}
|
|
715
|
-
)
|
|
716
|
-
] });
|
|
717
|
-
}
|
|
718
|
-
var DEFAULT_PASSWORD_CHANGE_DIALOG_LABELS = {
|
|
719
|
-
setNewPasswordTitle: "Set New Password",
|
|
720
|
-
changeMasterPasswordTitle: "Change Master Password",
|
|
721
|
-
recoveryDescription: "Set a new password for your recovered account",
|
|
722
|
-
changeDescription: "Change your master password dialog",
|
|
723
|
-
passwordChanged: "Password changed",
|
|
724
|
-
recoveryKeyUnchanged: "Your recovery key is unchanged: the one you saved still recovers this account.",
|
|
725
|
-
done: "Done",
|
|
726
|
-
recoverySuccessful: "Recovery successful. Set a new master password to continue.",
|
|
727
|
-
currentPassword: "Current Password",
|
|
728
|
-
currentPasswordPlaceholder: "Enter current password",
|
|
729
|
-
masterPassword: "Master Password",
|
|
730
|
-
newPassword: "New Password",
|
|
731
|
-
confirmPassword: "Confirm Password",
|
|
732
|
-
confirmNewPassword: "Confirm New Password",
|
|
733
|
-
cancel: "Cancel",
|
|
734
|
-
settingPassword: "Setting Password...",
|
|
735
|
-
changingPassword: "Changing Password...",
|
|
736
|
-
continue: "Continue",
|
|
737
|
-
changePassword: "Change Password"
|
|
738
|
-
};
|
|
739
|
-
function PasswordChangeDialog({
|
|
740
|
-
open,
|
|
741
|
-
onClose,
|
|
742
|
-
recoveryMode,
|
|
743
|
-
currentPassword,
|
|
744
|
-
onCurrentPasswordChange,
|
|
745
|
-
newPassword,
|
|
746
|
-
onNewPasswordChange,
|
|
747
|
-
confirmPassword,
|
|
748
|
-
onConfirmPasswordChange,
|
|
749
|
-
getUnmetRequirement,
|
|
750
|
-
error,
|
|
751
|
-
isProcessing,
|
|
752
|
-
isSubmitDisabled,
|
|
753
|
-
onSubmit,
|
|
754
|
-
isChanged,
|
|
755
|
-
success,
|
|
756
|
-
onDone,
|
|
757
|
-
labels,
|
|
758
|
-
passwordInputLabels,
|
|
759
|
-
testId,
|
|
760
|
-
testIds,
|
|
761
|
-
passwordInputTestIds
|
|
762
|
-
}) {
|
|
763
|
-
const currentPasswordId = useId();
|
|
764
|
-
const l = useMemo(() => ({ ...DEFAULT_PASSWORD_CHANGE_DIALOG_LABELS, ...labels }), [labels]);
|
|
765
|
-
const handleSubmit = (e) => {
|
|
766
|
-
e.preventDefault();
|
|
767
|
-
onSubmit();
|
|
768
|
-
};
|
|
769
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next && onClose(), children: /* @__PURE__ */ jsxs(
|
|
770
|
-
DialogContent,
|
|
771
|
-
{
|
|
772
|
-
presentation: "sheet",
|
|
773
|
-
className: "sm:max-w-md",
|
|
774
|
-
"data-testid": testIdOr(testId, { testId: "change-password-dialog" }),
|
|
775
|
-
children: [
|
|
776
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
777
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: recoveryMode ? l.setNewPasswordTitle : l.changeMasterPasswordTitle }),
|
|
778
|
-
/* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: recoveryMode ? l.recoveryDescription : l.changeDescription })
|
|
779
|
-
] }),
|
|
780
|
-
isChanged ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
781
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-green-text", children: [
|
|
782
|
-
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-5 w-5" }),
|
|
783
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: l.passwordChanged })
|
|
784
|
-
] }),
|
|
785
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.recoveryKeyUnchanged }),
|
|
786
|
-
success,
|
|
787
|
-
/* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
788
|
-
Button,
|
|
789
|
-
{
|
|
790
|
-
onClick: onDone,
|
|
791
|
-
"data-testid": testIdOr(testIds?.done, { testId: "change-password-done-button" }),
|
|
792
|
-
children: l.done
|
|
793
|
-
}
|
|
794
|
-
) })
|
|
795
|
-
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-3", children: [
|
|
796
|
-
recoveryMode && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-green-text", children: l.recoverySuccessful }),
|
|
797
|
-
!recoveryMode && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
798
|
-
/* @__PURE__ */ jsxs("label", { htmlFor: currentPasswordId, className: "text-sm font-medium text-foreground", children: [
|
|
799
|
-
l.currentPassword,
|
|
800
|
-
" ",
|
|
801
|
-
/* @__PURE__ */ jsx("span", { className: "text-red-text", children: "*" })
|
|
802
|
-
] }),
|
|
803
|
-
/* @__PURE__ */ jsx(
|
|
804
|
-
Input,
|
|
805
|
-
{
|
|
806
|
-
id: currentPasswordId,
|
|
807
|
-
type: "password",
|
|
808
|
-
value: currentPassword,
|
|
809
|
-
onChange: (e) => onCurrentPasswordChange(e.target.value),
|
|
810
|
-
disabled: isProcessing,
|
|
811
|
-
placeholder: l.currentPasswordPlaceholder,
|
|
812
|
-
autoComplete: "current-password",
|
|
813
|
-
className: "placeholder:text-muted-foreground",
|
|
814
|
-
"data-testid": testIdOr(testIds?.currentInput, {
|
|
815
|
-
testId: "change-password-current-input"
|
|
816
|
-
})
|
|
817
|
-
}
|
|
818
|
-
)
|
|
819
|
-
] }),
|
|
820
|
-
/* @__PURE__ */ jsx(
|
|
821
|
-
PasswordStrengthInput,
|
|
822
|
-
{
|
|
823
|
-
password: newPassword,
|
|
824
|
-
confirmPassword,
|
|
825
|
-
onPasswordChange: onNewPasswordChange,
|
|
826
|
-
onConfirmPasswordChange,
|
|
827
|
-
showConfirmation: true,
|
|
828
|
-
disabled: isProcessing,
|
|
829
|
-
passwordLabel: recoveryMode ? l.masterPassword : l.newPassword,
|
|
830
|
-
confirmLabel: recoveryMode ? l.confirmPassword : l.confirmNewPassword,
|
|
831
|
-
labels: passwordInputLabels,
|
|
832
|
-
testIds: passwordInputTestIds,
|
|
833
|
-
layout: recoveryMode ? "side-by-side" : "stacked",
|
|
834
|
-
showStrengthIndicator: true,
|
|
835
|
-
getUnmetRequirement
|
|
836
|
-
}
|
|
837
|
-
),
|
|
838
|
-
error && /* @__PURE__ */ jsx(
|
|
839
|
-
"div",
|
|
840
|
-
{
|
|
841
|
-
className: "rounded-md bg-red-bg p-3",
|
|
842
|
-
"data-testid": testIdOr(testIds?.error, { testId: "change-password-error" }),
|
|
843
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
844
|
-
/* @__PURE__ */ jsx(AlertCircle, { className: "h-5 w-5 flex-shrink-0 text-red-text" }),
|
|
845
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-red-text", children: error })
|
|
846
|
-
] })
|
|
847
|
-
}
|
|
848
|
-
),
|
|
849
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col-reverse sm:flex-row sm:justify-end gap-3 pt-4", children: [
|
|
850
|
-
!recoveryMode && /* @__PURE__ */ jsx(
|
|
851
|
-
Button,
|
|
852
|
-
{
|
|
853
|
-
type: "button",
|
|
854
|
-
variant: "outline",
|
|
855
|
-
onClick: onClose,
|
|
856
|
-
disabled: isProcessing,
|
|
857
|
-
"data-testid": testIdOr(testIds?.cancel, {
|
|
858
|
-
testId: "change-password-cancel-button"
|
|
859
|
-
}),
|
|
860
|
-
children: l.cancel
|
|
861
|
-
}
|
|
862
|
-
),
|
|
863
|
-
/* @__PURE__ */ jsx(
|
|
864
|
-
Button,
|
|
865
|
-
{
|
|
866
|
-
type: "submit",
|
|
867
|
-
disabled: isSubmitDisabled,
|
|
868
|
-
className: recoveryMode ? "w-full" : "",
|
|
869
|
-
"data-testid": testIdOr(testIds?.submit, { testId: "change-password-submit-button" }),
|
|
870
|
-
children: isProcessing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
871
|
-
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
872
|
-
recoveryMode ? l.settingPassword : l.changingPassword
|
|
873
|
-
] }) : recoveryMode ? l.continue : l.changePassword
|
|
874
|
-
}
|
|
875
|
-
)
|
|
876
|
-
] })
|
|
877
|
-
] })
|
|
878
|
-
]
|
|
879
|
-
}
|
|
880
|
-
) });
|
|
881
|
-
}
|
|
882
|
-
var DEFAULT_ACTIVE_SESSIONS_DIALOG_LABELS = {
|
|
883
|
-
title: "Active sessions",
|
|
884
|
-
description: "Devices and agents currently signed in to your account. Ending a session signs it out immediately.",
|
|
885
|
-
noSessions: "No active sessions.",
|
|
886
|
-
thisDevice: "This device",
|
|
887
|
-
agent: "Agent",
|
|
888
|
-
endSession: "End this session"
|
|
889
|
-
};
|
|
890
|
-
var DEFAULT_DELETE_ACCOUNT_DIALOG_LABELS = {
|
|
891
|
-
warningTitle: "Delete your account?",
|
|
892
|
-
warningBefore: "Once deleted, your account will be ",
|
|
893
|
-
warningEmphasis: "immediately closed and you will be logged out",
|
|
894
|
-
warningAfter: ". This action cannot be undone.",
|
|
895
|
-
blockersHeading: "You must resolve these first:",
|
|
896
|
-
cancel: "Cancel",
|
|
897
|
-
continue: "Continue",
|
|
898
|
-
confirmTitle: "Confirm account deletion",
|
|
899
|
-
confirmDescription: "Type your email address to confirm. Your account will be closed immediately and you will be logged out.",
|
|
900
|
-
yourEmail: "Your email",
|
|
901
|
-
back: "Back",
|
|
902
|
-
deleting: "Deleting...",
|
|
903
|
-
deleteAccount: "Delete Account"
|
|
904
|
-
};
|
|
905
|
-
function SessionListRow({
|
|
906
|
-
session,
|
|
907
|
-
onTerminate,
|
|
908
|
-
labels,
|
|
909
|
-
testIds
|
|
910
|
-
}) {
|
|
911
|
-
return /* @__PURE__ */ jsxs(
|
|
912
|
-
"div",
|
|
913
|
-
{
|
|
914
|
-
className: "flex w-full items-center gap-3 border-b border-border/60 px-4 py-3 last:border-b-0",
|
|
915
|
-
"data-testid": prefixedTestId(testIds?.sessionItem, session.id, {
|
|
916
|
-
testId: `session-item-${session.id}`
|
|
917
|
-
}),
|
|
918
|
-
children: [
|
|
919
|
-
/* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-muted", children: session.icon }),
|
|
920
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
921
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
922
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: session.name }),
|
|
923
|
-
session.isCurrent && /* @__PURE__ */ jsx(Badge, { className: "border-transparent bg-accent px-1.5 py-0 text-xs text-accent-foreground shadow-none hover:bg-accent", children: labels.thisDevice }),
|
|
924
|
-
session.isAgent && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "px-1 py-0 text-xs", children: labels.agent })
|
|
925
|
-
] }),
|
|
926
|
-
/* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: session.detail })
|
|
927
|
-
] }),
|
|
928
|
-
!session.isCurrent && /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
929
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
930
|
-
Button,
|
|
931
|
-
{
|
|
932
|
-
type: "button",
|
|
933
|
-
variant: "ghost",
|
|
934
|
-
size: "icon",
|
|
935
|
-
className: "h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive",
|
|
936
|
-
"aria-label": labels.endSession,
|
|
937
|
-
onClick: () => onTerminate(session.id),
|
|
938
|
-
disabled: session.isTerminating,
|
|
939
|
-
"data-testid": prefixedTestId(
|
|
940
|
-
testIds?.terminateSession,
|
|
941
|
-
session.id,
|
|
942
|
-
{ testId: `terminate-session-${session.id}-button` },
|
|
943
|
-
"-button"
|
|
944
|
-
),
|
|
945
|
-
children: session.isTerminating ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(LogOut, { className: "h-4 w-4" })
|
|
946
|
-
}
|
|
947
|
-
) }),
|
|
948
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: labels.endSession })
|
|
949
|
-
] })
|
|
950
|
-
]
|
|
951
|
-
}
|
|
952
|
-
);
|
|
953
|
-
}
|
|
954
|
-
function ActiveSessionsDialog({
|
|
955
|
-
open,
|
|
956
|
-
onOpenChange,
|
|
957
|
-
isLoading,
|
|
958
|
-
sessions,
|
|
959
|
-
onTerminate,
|
|
960
|
-
labels,
|
|
961
|
-
testId,
|
|
962
|
-
testIds
|
|
963
|
-
}) {
|
|
964
|
-
const l = useMemo(() => ({ ...DEFAULT_ACTIVE_SESSIONS_DIALOG_LABELS, ...labels }), [labels]);
|
|
965
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
966
|
-
DialogContent,
|
|
967
|
-
{
|
|
968
|
-
presentation: "sheet",
|
|
969
|
-
className: "sm:max-w-lg",
|
|
970
|
-
"data-testid": testIdOr(testId, { testId: "active-sessions-dialog" }),
|
|
971
|
-
children: [
|
|
972
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
973
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
974
|
-
/* @__PURE__ */ jsx(Radio, { className: "h-6 w-6" }),
|
|
975
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: l.title })
|
|
976
|
-
] }),
|
|
977
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: l.description })
|
|
978
|
-
] }),
|
|
979
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-8", children: /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin text-muted-foreground" }) }) : sessions.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-4 text-center text-sm text-muted-foreground", children: l.noSessions }) : /* @__PURE__ */ jsx(
|
|
980
|
-
"div",
|
|
981
|
-
{
|
|
982
|
-
className: "-mx-2 max-h-96 overflow-auto rounded-lg bg-muted",
|
|
983
|
-
"data-testid": testIdOr(testIds?.list, { testId: "session-list" }),
|
|
984
|
-
children: sessions.map((session) => /* @__PURE__ */ jsx(
|
|
985
|
-
SessionListRow,
|
|
986
|
-
{
|
|
987
|
-
session,
|
|
988
|
-
onTerminate,
|
|
989
|
-
labels: l,
|
|
990
|
-
testIds
|
|
991
|
-
},
|
|
992
|
-
session.id
|
|
993
|
-
))
|
|
994
|
-
}
|
|
995
|
-
)
|
|
996
|
-
]
|
|
997
|
-
}
|
|
998
|
-
) });
|
|
999
|
-
}
|
|
1000
|
-
function DeleteAccountDialog({
|
|
1001
|
-
open,
|
|
1002
|
-
onClose,
|
|
1003
|
-
step,
|
|
1004
|
-
blockers,
|
|
1005
|
-
onContinue,
|
|
1006
|
-
onBack,
|
|
1007
|
-
userEmail,
|
|
1008
|
-
confirmEmail,
|
|
1009
|
-
onConfirmEmailChange,
|
|
1010
|
-
isDeleting,
|
|
1011
|
-
onSubmit,
|
|
1012
|
-
labels,
|
|
1013
|
-
testId,
|
|
1014
|
-
testIds
|
|
1015
|
-
}) {
|
|
1016
|
-
const confirmEmailId = useId();
|
|
1017
|
-
const l = useMemo(() => ({ ...DEFAULT_DELETE_ACCOUNT_DIALOG_LABELS, ...labels }), [labels]);
|
|
1018
|
-
const emailMatches = confirmEmail.toLowerCase() === userEmail.toLowerCase();
|
|
1019
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: onClose, children: /* @__PURE__ */ jsx(
|
|
1020
|
-
DialogContent,
|
|
1021
|
-
{
|
|
1022
|
-
presentation: "sheet",
|
|
1023
|
-
className: "sm:max-w-md",
|
|
1024
|
-
"data-testid": testIdOr(testId, { testId: "delete-account-dialog" }),
|
|
1025
|
-
children: step === "warning" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1026
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1027
|
-
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
1028
|
-
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-destructive" }),
|
|
1029
|
-
l.warningTitle
|
|
1030
|
-
] }),
|
|
1031
|
-
/* @__PURE__ */ jsxs(DialogDescription, { children: [
|
|
1032
|
-
l.warningBefore,
|
|
1033
|
-
/* @__PURE__ */ jsx("strong", { children: l.warningEmphasis }),
|
|
1034
|
-
l.warningAfter
|
|
1035
|
-
] })
|
|
1036
|
-
] }),
|
|
1037
|
-
blockers.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-yellow-bg p-3 text-sm text-yellow-text", children: [
|
|
1038
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 font-semibold", children: l.blockersHeading }),
|
|
1039
|
-
/* @__PURE__ */ jsx("ul", { className: "list-inside list-disc space-y-1", children: blockers.map((blocker) => /* @__PURE__ */ jsx("li", { children: blocker.content }, blocker.key)) })
|
|
1040
|
-
] }),
|
|
1041
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col-reverse sm:flex-row sm:justify-end gap-2 pt-2", children: [
|
|
1042
|
-
/* @__PURE__ */ jsx(
|
|
1043
|
-
Button,
|
|
1044
|
-
{
|
|
1045
|
-
variant: "outline",
|
|
1046
|
-
onClick: onClose,
|
|
1047
|
-
"data-testid": testIdOr(testIds?.cancel, { testId: "delete-account-cancel-button" }),
|
|
1048
|
-
children: l.cancel
|
|
1049
|
-
}
|
|
1050
|
-
),
|
|
1051
|
-
/* @__PURE__ */ jsx(
|
|
1052
|
-
Button,
|
|
1053
|
-
{
|
|
1054
|
-
variant: "destructive",
|
|
1055
|
-
disabled: blockers.length > 0,
|
|
1056
|
-
onClick: onContinue,
|
|
1057
|
-
"data-testid": testIdOr(testIds?.continue, {
|
|
1058
|
-
testId: "delete-account-continue-button"
|
|
1059
|
-
}),
|
|
1060
|
-
children: l.continue
|
|
1061
|
-
}
|
|
1062
|
-
)
|
|
1063
|
-
] })
|
|
1064
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1065
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1066
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: l.confirmTitle }),
|
|
1067
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: l.confirmDescription })
|
|
1068
|
-
] }),
|
|
1069
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1070
|
-
/* @__PURE__ */ jsx("label", { htmlFor: confirmEmailId, className: "mb-1 block text-sm font-medium", children: l.yourEmail }),
|
|
1071
|
-
/* @__PURE__ */ jsx(
|
|
1072
|
-
Input,
|
|
1073
|
-
{
|
|
1074
|
-
id: confirmEmailId,
|
|
1075
|
-
type: "email",
|
|
1076
|
-
placeholder: userEmail,
|
|
1077
|
-
value: confirmEmail,
|
|
1078
|
-
onChange: (e) => onConfirmEmailChange(e.target.value),
|
|
1079
|
-
autoFocus: true,
|
|
1080
|
-
"data-testid": testIdOr(testIds?.emailInput, {
|
|
1081
|
-
testId: "delete-account-email-input"
|
|
1082
|
-
})
|
|
1083
|
-
}
|
|
1084
|
-
)
|
|
1085
|
-
] }),
|
|
1086
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col-reverse sm:flex-row sm:justify-end gap-2 pt-2", children: [
|
|
1087
|
-
/* @__PURE__ */ jsx(
|
|
1088
|
-
Button,
|
|
1089
|
-
{
|
|
1090
|
-
variant: "outline",
|
|
1091
|
-
onClick: onBack,
|
|
1092
|
-
"data-testid": testIdOr(testIds?.back, { testId: "delete-account-back-button" }),
|
|
1093
|
-
children: l.back
|
|
1094
|
-
}
|
|
1095
|
-
),
|
|
1096
|
-
/* @__PURE__ */ jsx(
|
|
1097
|
-
Button,
|
|
1098
|
-
{
|
|
1099
|
-
variant: "destructive",
|
|
1100
|
-
disabled: !emailMatches || isDeleting,
|
|
1101
|
-
onClick: onSubmit,
|
|
1102
|
-
"data-testid": testIdOr(testIds?.submit, { testId: "delete-account-submit-button" }),
|
|
1103
|
-
children: isDeleting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1104
|
-
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
1105
|
-
l.deleting
|
|
1106
|
-
] }) : l.deleteAccount
|
|
1107
|
-
}
|
|
1108
|
-
)
|
|
1109
|
-
] })
|
|
1110
|
-
] })
|
|
1111
|
-
}
|
|
1112
|
-
) });
|
|
1113
|
-
}
|
|
1114
|
-
var DEFAULT_LOGOUT_DIALOG_LABELS = {
|
|
1115
|
-
title: "Logout",
|
|
1116
|
-
descriptionAll: "End this session or all active sessions?",
|
|
1117
|
-
descriptionThis: "End this session and return to the login page.",
|
|
1118
|
-
cancel: "Cancel",
|
|
1119
|
-
allSessions: "All sessions",
|
|
1120
|
-
offlineTooltip: "Ending all sessions needs a connection \u2014 you can still log out of this device.",
|
|
1121
|
-
thisSession: "This session",
|
|
1122
|
-
offlineNote: "You\u2019re offline \u2014 ending all sessions needs a connection. You can still log out of this device.",
|
|
1123
|
-
activeSessions: (count) => formatCount(count, { one: "active session", other: "active sessions" }),
|
|
1124
|
-
workspaces: (count) => formatCount(count, { one: "workspace", other: "workspaces" }),
|
|
1125
|
-
ttl: (ttlLabel) => `TTL ${ttlLabel}`
|
|
1126
|
-
};
|
|
1127
|
-
function SessionRow({
|
|
1128
|
-
session,
|
|
1129
|
-
icon,
|
|
1130
|
-
labels
|
|
1131
|
-
}) {
|
|
1132
|
-
const { status } = session;
|
|
1133
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 rounded-md bg-muted/50 px-3 py-2", children: [
|
|
1134
|
-
icon && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: icon }),
|
|
1135
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1136
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1137
|
-
/* @__PURE__ */ jsx("code", { className: "truncate font-mono text-sm", children: session.id.slice(0, 12) }),
|
|
1138
|
-
/* @__PURE__ */ jsx(
|
|
1139
|
-
Badge,
|
|
1140
|
-
{
|
|
1141
|
-
variant: status === "agent" ? "default" : "secondary",
|
|
1142
|
-
className: "px-1 py-0 text-sm",
|
|
1143
|
-
children: status
|
|
1144
|
-
}
|
|
1145
|
-
)
|
|
1146
|
-
] }),
|
|
1147
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
1148
|
-
session.ipAddress && /* @__PURE__ */ jsx("span", { children: session.ipAddress }),
|
|
1149
|
-
/* @__PURE__ */ jsx("span", { children: labels.ttl(session.ttlLabel) }),
|
|
1150
|
-
session.workspaceCount > 0 && /* @__PURE__ */ jsx("span", { children: labels.workspaces(session.workspaceCount) })
|
|
1151
|
-
] })
|
|
1152
|
-
] })
|
|
1153
|
-
] });
|
|
1154
|
-
}
|
|
1155
|
-
function LogoutDialog({
|
|
1156
|
-
open,
|
|
1157
|
-
onClose,
|
|
1158
|
-
onLogoutThis,
|
|
1159
|
-
onLogoutAll,
|
|
1160
|
-
canLogoutAll,
|
|
1161
|
-
isOnline,
|
|
1162
|
-
sessions,
|
|
1163
|
-
renderSessionIcon,
|
|
1164
|
-
labels,
|
|
1165
|
-
testId,
|
|
1166
|
-
testIds
|
|
1167
|
-
}) {
|
|
1168
|
-
const l = useMemo(() => ({ ...DEFAULT_LOGOUT_DIALOG_LABELS, ...labels }), [labels]);
|
|
1169
|
-
const [sessionsOpen, setSessionsOpen] = useState(false);
|
|
1170
|
-
const restoreFocus = useRestoreFocus();
|
|
1171
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next && onClose(), children: /* @__PURE__ */ jsxs(
|
|
1172
|
-
DialogContent,
|
|
1173
|
-
{
|
|
1174
|
-
...restoreFocus,
|
|
1175
|
-
className: "sm:max-w-md",
|
|
1176
|
-
"data-testid": testIdOr(testId, { testId: "logout-modal" }),
|
|
1177
|
-
children: [
|
|
1178
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1179
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1180
|
-
/* @__PURE__ */ jsx(LogOut, { className: "h-6 w-6" }),
|
|
1181
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: l.title })
|
|
1182
|
-
] }),
|
|
1183
|
-
/* @__PURE__ */ jsx(DialogDescription, { className: "text-base", children: canLogoutAll ? l.descriptionAll : l.descriptionThis })
|
|
1184
|
-
] }),
|
|
1185
|
-
/* @__PURE__ */ jsxs(DialogFooter, { className: "gap-2", children: [
|
|
1186
|
-
/* @__PURE__ */ jsx(
|
|
1187
|
-
Button,
|
|
1188
|
-
{
|
|
1189
|
-
variant: "outline",
|
|
1190
|
-
onClick: onClose,
|
|
1191
|
-
"data-testid": testIdOr(testIds?.cancel, { testId: "logout-modal-cancel-button" }),
|
|
1192
|
-
children: l.cancel
|
|
1193
|
-
}
|
|
1194
|
-
),
|
|
1195
|
-
canLogoutAll && /* @__PURE__ */ jsx(
|
|
1196
|
-
Button,
|
|
1197
|
-
{
|
|
1198
|
-
variant: "secondary",
|
|
1199
|
-
onClick: onLogoutAll,
|
|
1200
|
-
disabled: !isOnline,
|
|
1201
|
-
title: isOnline ? void 0 : l.offlineTooltip,
|
|
1202
|
-
"data-testid": testIdOr(testIds?.all, { testId: "logout-modal-all-button" }),
|
|
1203
|
-
children: l.allSessions
|
|
1204
|
-
}
|
|
1205
|
-
),
|
|
1206
|
-
/* @__PURE__ */ jsx(
|
|
1207
|
-
Button,
|
|
1208
|
-
{
|
|
1209
|
-
variant: "default",
|
|
1210
|
-
onClick: onLogoutThis,
|
|
1211
|
-
"data-testid": testIdOr(testIds?.this, { testId: "logout-modal-this-button" }),
|
|
1212
|
-
children: l.thisSession
|
|
1213
|
-
}
|
|
1214
|
-
)
|
|
1215
|
-
] }),
|
|
1216
|
-
canLogoutAll && !isOnline && /* @__PURE__ */ jsx(
|
|
1217
|
-
"p",
|
|
1218
|
-
{
|
|
1219
|
-
className: "text-sm text-muted-foreground",
|
|
1220
|
-
"data-testid": testIdOr(testIds?.offlineNote, { testId: "logout-offline-note" }),
|
|
1221
|
-
children: l.offlineNote
|
|
1222
|
-
}
|
|
1223
|
-
),
|
|
1224
|
-
sessions.length > 0 && /* @__PURE__ */ jsxs(Collapsible, { open: sessionsOpen, onOpenChange: setSessionsOpen, children: [
|
|
1225
|
-
/* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex w-full items-center gap-2 py-1 text-left transition-opacity hover:opacity-80 pointer-coarse:py-3", children: [
|
|
1226
|
-
sessionsOpen ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 flex-shrink-0" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 flex-shrink-0" }),
|
|
1227
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-muted-foreground", children: [
|
|
1228
|
-
/* @__PURE__ */ jsx(Radio, { className: "h-3 w-3" }),
|
|
1229
|
-
/* @__PURE__ */ jsx("span", { children: l.activeSessions(sessions.length) })
|
|
1230
|
-
] })
|
|
1231
|
-
] }),
|
|
1232
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "max-h-48 space-y-1.5 overflow-auto pt-2", children: sessions.map((session) => /* @__PURE__ */ jsx(
|
|
1233
|
-
SessionRow,
|
|
1234
|
-
{
|
|
1235
|
-
session,
|
|
1236
|
-
icon: renderSessionIcon?.(session.status),
|
|
1237
|
-
labels: l
|
|
1238
|
-
},
|
|
1239
|
-
session.id
|
|
1240
|
-
)) }) })
|
|
1241
|
-
] })
|
|
1242
|
-
]
|
|
1243
|
-
}
|
|
1244
|
-
) });
|
|
1245
|
-
}
|
|
1246
|
-
function SettingsSwitchRow({
|
|
1247
|
-
id,
|
|
1248
|
-
title,
|
|
1249
|
-
icon,
|
|
1250
|
-
description,
|
|
1251
|
-
checked,
|
|
1252
|
-
onCheckedChange,
|
|
1253
|
-
testId,
|
|
1254
|
-
disabled,
|
|
1255
|
-
className
|
|
1256
|
-
}) {
|
|
1257
|
-
return /* @__PURE__ */ jsxs(
|
|
1258
|
-
"div",
|
|
1259
|
-
{
|
|
1260
|
-
"data-slot": "settings-switch-row",
|
|
1261
|
-
className: cn("flex items-center justify-between gap-4", className),
|
|
1262
|
-
children: [
|
|
1263
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1264
|
-
/* @__PURE__ */ jsxs("label", { htmlFor: id, className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
1265
|
-
icon,
|
|
1266
|
-
title
|
|
1267
|
-
] }),
|
|
1268
|
-
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
1269
|
-
] }),
|
|
1270
|
-
/* @__PURE__ */ jsx(
|
|
1271
|
-
Switch,
|
|
1272
|
-
{
|
|
1273
|
-
id,
|
|
1274
|
-
checked,
|
|
1275
|
-
onCheckedChange,
|
|
1276
|
-
disabled,
|
|
1277
|
-
"data-testid": testId
|
|
1278
|
-
}
|
|
1279
|
-
)
|
|
1280
|
-
]
|
|
1281
|
-
}
|
|
1282
|
-
);
|
|
1283
|
-
}
|
|
1284
|
-
function SettingsSwitchGroup({
|
|
1285
|
-
className,
|
|
1286
|
-
children
|
|
1287
|
-
}) {
|
|
1288
|
-
return /* @__PURE__ */ jsx(
|
|
1289
|
-
"div",
|
|
1290
|
-
{
|
|
1291
|
-
"data-slot": "settings-switch-group",
|
|
1292
|
-
className: cn("ml-6 space-y-4 border-l border-border pl-4", className),
|
|
1293
|
-
children
|
|
1294
|
-
}
|
|
1295
|
-
);
|
|
1296
|
-
}
|
|
1297
|
-
function NotificationCategoryList({
|
|
1298
|
-
masterId,
|
|
1299
|
-
masterTitle,
|
|
1300
|
-
masterDescription,
|
|
1301
|
-
masterChecked,
|
|
1302
|
-
onMasterChange,
|
|
1303
|
-
masterTestId,
|
|
1304
|
-
categories,
|
|
1305
|
-
onCategoryChange,
|
|
1306
|
-
idPrefix = masterId,
|
|
1307
|
-
testIdPrefix
|
|
1308
|
-
}) {
|
|
1309
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "notification-category-list", children: [
|
|
1310
|
-
/* @__PURE__ */ jsx(
|
|
1311
|
-
SettingsSwitchRow,
|
|
1312
|
-
{
|
|
1313
|
-
id: masterId,
|
|
1314
|
-
title: masterTitle,
|
|
1315
|
-
description: masterDescription,
|
|
1316
|
-
checked: masterChecked,
|
|
1317
|
-
onCheckedChange: onMasterChange,
|
|
1318
|
-
testId: testIdOr(masterTestId, { testId: "toggle-email-notifications" })
|
|
1319
|
-
}
|
|
1320
|
-
),
|
|
1321
|
-
/* @__PURE__ */ jsx("div", { className: "ml-1 mt-3 space-y-3 border-l border-border pl-4 pointer-coarse:mt-5 pointer-coarse:space-y-5", children: categories.map((c) => /* @__PURE__ */ jsxs(
|
|
1322
|
-
"label",
|
|
1323
|
-
{
|
|
1324
|
-
htmlFor: `${idPrefix}-${c.key}`,
|
|
1325
|
-
className: cn(
|
|
1326
|
-
"flex items-start gap-3 pointer-coarse:min-h-11",
|
|
1327
|
-
masterChecked ? "cursor-pointer" : "cursor-not-allowed opacity-50"
|
|
1328
|
-
),
|
|
1329
|
-
children: [
|
|
1330
|
-
/* @__PURE__ */ jsx(
|
|
1331
|
-
Checkbox,
|
|
1332
|
-
{
|
|
1333
|
-
id: `${idPrefix}-${c.key}`,
|
|
1334
|
-
checked: c.checked,
|
|
1335
|
-
disabled: !masterChecked,
|
|
1336
|
-
onCheckedChange: (value) => onCategoryChange(c.key, value === true),
|
|
1337
|
-
"data-testid": prefixedTestId(testIdPrefix, c.key, { testId: `toggle-email-${c.key}` }),
|
|
1338
|
-
className: "mt-0.5 size-5 shrink-0"
|
|
1339
|
-
}
|
|
1340
|
-
),
|
|
1341
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1342
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm", children: c.label }),
|
|
1343
|
-
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: c.description })
|
|
1344
|
-
] })
|
|
1345
|
-
]
|
|
1346
|
-
},
|
|
1347
|
-
c.key
|
|
1348
|
-
)) })
|
|
1349
|
-
] });
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
// src/settings/account-views.ts
|
|
1353
|
-
function formatSessionTtl(totalSeconds) {
|
|
1354
|
-
if (totalSeconds <= 0) return "expired";
|
|
1355
|
-
const days = Math.floor(totalSeconds / 86400);
|
|
1356
|
-
const hours = Math.floor(totalSeconds % 86400 / 3600);
|
|
1357
|
-
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
1358
|
-
const parts = [];
|
|
1359
|
-
if (days > 0) parts.push(`${days}d`);
|
|
1360
|
-
if (hours > 0) parts.push(`${hours}h`);
|
|
1361
|
-
if (minutes > 0) parts.push(`${minutes}m`);
|
|
1362
|
-
return parts.length > 0 ? parts.join(" ") : "<1m";
|
|
1363
|
-
}
|
|
1364
|
-
function toActiveSessionViews(sessions, {
|
|
1365
|
-
currentSessionId,
|
|
1366
|
-
terminatingId,
|
|
1367
|
-
renderIcon,
|
|
1368
|
-
formatTtl = formatSessionTtl
|
|
1369
|
-
}) {
|
|
1370
|
-
return sessions.map((session) => {
|
|
1371
|
-
const status = session.status || "user";
|
|
1372
|
-
const count = session.workspaces.length;
|
|
1373
|
-
return {
|
|
1374
|
-
id: session.session_id,
|
|
1375
|
-
name: session.name || (status === "agent" ? "Agent session" : "Browser session"),
|
|
1376
|
-
isCurrent: session.session_id === currentSessionId,
|
|
1377
|
-
isAgent: status === "agent",
|
|
1378
|
-
detail: `${session.ip_address ?? "Unknown IP"} \xB7 expires in ${formatTtl(session.ttl)}${count > 0 ? ` \xB7 ${count} workspace${count > 1 ? "s" : ""}` : ""}`,
|
|
1379
|
-
isTerminating: terminatingId === session.session_id,
|
|
1380
|
-
icon: renderIcon?.(status)
|
|
1381
|
-
};
|
|
1382
|
-
}).sort((a, b) => Number(b.isCurrent) - Number(a.isCurrent));
|
|
1383
|
-
}
|
|
1384
|
-
function toLogoutSessionViews(sessions, formatTtl = formatSessionTtl) {
|
|
1385
|
-
return sessions.map((session) => ({
|
|
1386
|
-
id: session.session_id,
|
|
1387
|
-
status: session.status || "user",
|
|
1388
|
-
ipAddress: session.ip_address,
|
|
1389
|
-
ttlLabel: formatTtl(session.ttl),
|
|
1390
|
-
workspaceCount: session.workspaces.length
|
|
1391
|
-
}));
|
|
1392
|
-
}
|
|
1393
|
-
function toDeleteBlockerViews(blockers, renderSubscriptionLink) {
|
|
1394
|
-
return blockers.flatMap(
|
|
1395
|
-
(blocker) => blocker.type === "active_subscription" ? [
|
|
1396
|
-
{
|
|
1397
|
-
key: "active_subscription",
|
|
1398
|
-
content: renderSubscriptionLink ? renderSubscriptionLink() : "Active subscription: cancel it in your subscription settings first"
|
|
1399
|
-
}
|
|
1400
|
-
] : blocker.workspaces.map((ws) => ({
|
|
1401
|
-
key: `workspace-${ws}`,
|
|
1402
|
-
content: `You are the sole admin of workspace "${ws}" \u2014 transfer admin rights or remove all other members first`
|
|
1403
|
-
}))
|
|
1404
|
-
);
|
|
1405
|
-
}
|
|
1406
|
-
var EMAIL_NOTIFICATION_CATEGORIES = [
|
|
1407
|
-
{ key: "messages", label: "New messages", description: "A direct message while you\u2019re offline" },
|
|
1408
|
-
{ key: "workspace_added", label: "Workspace access", description: "You\u2019re added to a workspace" },
|
|
1409
|
-
{
|
|
1410
|
-
key: "contact_accepted",
|
|
1411
|
-
label: "Invitation accepted",
|
|
1412
|
-
description: "Someone accepts your invitation"
|
|
1413
|
-
},
|
|
1414
|
-
{ key: "referral_reward", label: "Rewards", description: "You earn a reward" },
|
|
1415
|
-
{
|
|
1416
|
-
key: "product_updates",
|
|
1417
|
-
label: "ARBI update",
|
|
1418
|
-
description: "Weekly digest of new features and highlights"
|
|
1419
|
-
}
|
|
1420
|
-
];
|
|
1421
|
-
var EMAIL_NOTIFICATION_KEYS = EMAIL_NOTIFICATION_CATEGORIES.map(
|
|
1422
|
-
(c) => c.key
|
|
1423
|
-
);
|
|
1424
|
-
function toNotificationCategories(checked, defs = EMAIL_NOTIFICATION_CATEGORIES) {
|
|
1425
|
-
return defs.map((def) => ({ ...def, checked: checked[def.key] ?? true }));
|
|
1426
|
-
}
|
|
1427
|
-
function PanelFrame({ testId, className, children }) {
|
|
1428
|
-
return /* @__PURE__ */ jsx(
|
|
1429
|
-
"div",
|
|
1430
|
-
{
|
|
1431
|
-
"data-slot": "panel-frame",
|
|
1432
|
-
"data-testid": testId,
|
|
1433
|
-
className: cn("flex h-full min-h-0 flex-col bg-background", className),
|
|
1434
|
-
children
|
|
1435
|
-
}
|
|
1436
|
-
);
|
|
1437
|
-
}
|
|
1438
|
-
function PanelFrameBody({ className, children }) {
|
|
1439
|
-
return /* @__PURE__ */ jsx("div", { "data-slot": "panel-frame-body", className: cn("min-h-0 flex-1 overflow-hidden", className), children });
|
|
1440
|
-
}
|
|
1441
|
-
function PanelScroll({ variant = "flush", className, children }) {
|
|
1442
|
-
return /* @__PURE__ */ jsx(
|
|
1443
|
-
"div",
|
|
1444
|
-
{
|
|
1445
|
-
"data-slot": "panel-scroll",
|
|
1446
|
-
className: cn("h-full overflow-auto", variant === "padded" && "space-y-4 p-3", className),
|
|
1447
|
-
children
|
|
1448
|
-
}
|
|
1449
|
-
);
|
|
1450
|
-
}
|
|
1451
|
-
function PanelActionsRow({
|
|
1452
|
-
className,
|
|
1453
|
-
children
|
|
1454
|
-
}) {
|
|
1455
|
-
return /* @__PURE__ */ jsx("div", { "data-slot": "panel-actions-row", className: cn("flex justify-end", className), children });
|
|
1456
|
-
}
|
|
1457
|
-
function PanelAddButton({
|
|
1458
|
-
label,
|
|
1459
|
-
onClick,
|
|
1460
|
-
isCompact,
|
|
1461
|
-
icon,
|
|
1462
|
-
testId,
|
|
1463
|
-
disabledReason
|
|
1464
|
-
}) {
|
|
1465
|
-
return /* @__PURE__ */ jsxs(
|
|
1466
|
-
"button",
|
|
1467
|
-
{
|
|
1468
|
-
type: "button",
|
|
1469
|
-
onClick,
|
|
1470
|
-
disabled: !!disabledReason,
|
|
1471
|
-
title: disabledReason ?? label,
|
|
1472
|
-
"data-slot": "panel-add-button",
|
|
1473
|
-
"data-testid": testId,
|
|
1474
|
-
className: "flex h-8 items-center gap-1.5 rounded-md px-2 text-sm font-medium text-primary transition-colors hover:bg-primary/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent pointer-coarse:h-11 pointer-coarse:min-w-11",
|
|
1475
|
-
children: [
|
|
1476
|
-
icon,
|
|
1477
|
-
isCompact ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: label }) : /* @__PURE__ */ jsx("span", { children: "New" })
|
|
1478
|
-
]
|
|
1479
|
-
}
|
|
1480
|
-
);
|
|
1481
|
-
}
|
|
1482
|
-
function PanelTitleBar({
|
|
1483
|
-
icon,
|
|
1484
|
-
title,
|
|
1485
|
-
end
|
|
1486
|
-
}) {
|
|
1487
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "panel-title-bar", className: "flex w-full items-center justify-between px-4 py-2", children: [
|
|
1488
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1489
|
-
icon,
|
|
1490
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: title })
|
|
1491
|
-
] }),
|
|
1492
|
-
end
|
|
1493
|
-
] });
|
|
1494
|
-
}
|
|
1495
|
-
function PanelNote({ children }) {
|
|
1496
|
-
return /* @__PURE__ */ jsx("div", { "data-slot": "panel-note", className: "py-8 text-center text-muted-foreground", children });
|
|
1497
|
-
}
|
|
1498
|
-
function resolveSettingsSection(sections, id) {
|
|
1499
|
-
return sections.find((section) => section.id === id) ?? sections[0];
|
|
1500
|
-
}
|
|
1501
|
-
function SettingsPage({
|
|
1502
|
-
sections,
|
|
1503
|
-
activeSectionId,
|
|
1504
|
-
onSectionChange,
|
|
1505
|
-
title = "Settings",
|
|
1506
|
-
headerActions,
|
|
1507
|
-
children,
|
|
1508
|
-
testId = "settings-page"
|
|
1509
|
-
}) {
|
|
1510
|
-
const active = resolveSettingsSection(sections, activeSectionId);
|
|
1511
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1512
|
-
/* @__PURE__ */ jsxs(PanelFrame, { testId, children: [
|
|
1513
|
-
/* @__PURE__ */ jsx(DraggableHeader, { children: /* @__PURE__ */ jsx(
|
|
1514
|
-
TabHeader,
|
|
1515
|
-
{
|
|
1516
|
-
tabs: sections.map(({ id, label, icon }) => ({ id, label, icon })),
|
|
1517
|
-
activeTabId: active?.id ?? "",
|
|
1518
|
-
onTabChange: onSectionChange,
|
|
1519
|
-
variant: "underline",
|
|
1520
|
-
compactBreakpoint: 0,
|
|
1521
|
-
rightContent: () => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1522
|
-
active?.actions,
|
|
1523
|
-
headerActions
|
|
1524
|
-
] })
|
|
1525
|
-
}
|
|
1526
|
-
) }),
|
|
1527
|
-
/* @__PURE__ */ jsxs(PanelFrameBody, { className: "overflow-auto px-6 pb-6 pt-4", children: [
|
|
1528
|
-
/* @__PURE__ */ jsx("h1", { className: "mx-auto mb-4 w-full max-w-2xl text-xl font-semibold text-foreground", children: title }),
|
|
1529
|
-
active?.render()
|
|
1530
|
-
] })
|
|
1531
|
-
] }),
|
|
1532
|
-
children
|
|
1533
|
-
] });
|
|
1534
|
-
}
|
|
1535
|
-
var DOT = {
|
|
1536
|
-
connected: "bg-green-solid",
|
|
1537
|
-
connecting: "bg-yellow-solid",
|
|
1538
|
-
disconnected: "bg-red-solid",
|
|
1539
|
-
offline: "bg-yellow-solid"
|
|
1540
|
-
};
|
|
1541
|
-
function ServerConnectionButton({
|
|
1542
|
-
state,
|
|
1543
|
-
label,
|
|
1544
|
-
isRefreshing,
|
|
1545
|
-
onRefresh,
|
|
1546
|
-
testId = "refresh-session-button"
|
|
1547
|
-
}) {
|
|
1548
|
-
return /* @__PURE__ */ jsxs(
|
|
1549
|
-
Button,
|
|
1550
|
-
{
|
|
1551
|
-
type: "button",
|
|
1552
|
-
variant: "outline",
|
|
1553
|
-
size: "sm",
|
|
1554
|
-
onClick: onRefresh,
|
|
1555
|
-
disabled: isRefreshing,
|
|
1556
|
-
className: "flex items-center gap-2",
|
|
1557
|
-
"data-testid": testId,
|
|
1558
|
-
"data-state": state,
|
|
1559
|
-
children: [
|
|
1560
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: cn("size-4", isRefreshing && "animate-spin") }),
|
|
1561
|
-
/* @__PURE__ */ jsx("span", { className: cn("size-2 rounded-full", DOT[state]), "aria-hidden": true }),
|
|
1562
|
-
label
|
|
1563
|
-
]
|
|
1564
|
-
}
|
|
1565
|
-
);
|
|
1566
|
-
}
|
|
1567
|
-
var DEFAULT_WORK_OFFLINE_LABELS = {
|
|
1568
|
-
goOnline: "Go online",
|
|
1569
|
-
workOffline: "Work offline",
|
|
1570
|
-
goOnlineHint: "Reconnect and use ARBI online again",
|
|
1571
|
-
workOfflineHint: "Work offline \u2014 read cached docs and queue edits, even though the server is reachable"
|
|
1572
|
-
};
|
|
1573
|
-
function WorkOfflineToggle({
|
|
1574
|
-
isOffline,
|
|
1575
|
-
onToggle,
|
|
1576
|
-
labels,
|
|
1577
|
-
testId = "work-offline-toggle"
|
|
1578
|
-
}) {
|
|
1579
|
-
const l = { ...DEFAULT_WORK_OFFLINE_LABELS, ...labels };
|
|
1580
|
-
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
1581
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1582
|
-
Button,
|
|
1583
|
-
{
|
|
1584
|
-
variant: isOffline ? "secondary" : "outline",
|
|
1585
|
-
size: "icon",
|
|
1586
|
-
onClick: () => onToggle(!isOffline),
|
|
1587
|
-
"aria-label": isOffline ? l.goOnline : l.workOffline,
|
|
1588
|
-
"aria-pressed": isOffline,
|
|
1589
|
-
"data-testid": testId,
|
|
1590
|
-
children: isOffline ? /* @__PURE__ */ jsx(Wifi, { className: "size-4" }) : /* @__PURE__ */ jsx(WifiOff, { className: "size-4" })
|
|
1591
|
-
}
|
|
1592
|
-
) }),
|
|
1593
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: isOffline ? l.goOnlineHint : l.workOfflineHint }) })
|
|
1594
|
-
] });
|
|
1595
|
-
}
|
|
1596
|
-
function serverConnectionView({ status, forcedOffline = false, deviceOffline = false }, domain) {
|
|
1597
|
-
const state = forcedOffline || deviceOffline ? "offline" : status === "error" ? "disconnected" : status;
|
|
1598
|
-
const label = forcedOffline ? "Working offline" : deviceOffline ? "Offline" : status === "connected" ? "Connected" : status === "connecting" ? "Connecting" : "Disconnected";
|
|
1599
|
-
const description = deviceOffline && !forcedOffline ? "You're offline. ARBI reconnects by itself when your connection returns." : `${status === "connected" ? `Connected to ${domain}.` : status === "connecting" ? `Connecting to ${domain}...` : `Disconnected from ${domain}.`} Click to refresh your session.`;
|
|
1600
|
-
return { state, label, description };
|
|
1601
|
-
}
|
|
1602
|
-
var GRID_ACCENT_CLASSES = [
|
|
1603
|
-
"[&_.ag-checkbox-input-wrapper.ag-checked]:!bg-primary",
|
|
1604
|
-
"[&_.ag-checkbox-input-wrapper.ag-checked]:!border-primary",
|
|
1605
|
-
"[&_.ag-checkbox-input-wrapper.ag-checked]:!text-primary-foreground"
|
|
1606
|
-
];
|
|
1607
|
-
var GRID_ACCENT_VARS = {
|
|
1608
|
-
"--ag-checkbox-checked-color": "hsl(var(--primary))",
|
|
1609
|
-
"--ag-selected-row-background-color": "hsl(var(--accent))"
|
|
1610
|
-
};
|
|
1611
|
-
function PremiumModelsFrame({
|
|
1612
|
-
enabled,
|
|
1613
|
-
onEnabledChange,
|
|
1614
|
-
title = "Enable Premium Models",
|
|
1615
|
-
description = "Third party AI models are priced on a pass-through basis.",
|
|
1616
|
-
children,
|
|
1617
|
-
toggleTestId
|
|
1618
|
-
}) {
|
|
1619
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "premium-models-frame", children: [
|
|
1620
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-3", children: [
|
|
1621
|
-
/* @__PURE__ */ jsx(
|
|
1622
|
-
Switch,
|
|
1623
|
-
{
|
|
1624
|
-
id: "premiumModelToggle",
|
|
1625
|
-
checked: enabled,
|
|
1626
|
-
onCheckedChange: onEnabledChange,
|
|
1627
|
-
"data-testid": testIdOr(toggleTestId, { testId: "toggle-premium-model" })
|
|
1628
|
-
}
|
|
1629
|
-
),
|
|
1630
|
-
/* @__PURE__ */ jsxs(
|
|
1631
|
-
"label",
|
|
1632
|
-
{
|
|
1633
|
-
className: "flex cursor-pointer items-center gap-2 text-sm font-medium",
|
|
1634
|
-
htmlFor: "premiumModelToggle",
|
|
1635
|
-
children: [
|
|
1636
|
-
/* @__PURE__ */ jsx(Crown, { className: "size-4 text-muted-foreground" }),
|
|
1637
|
-
title
|
|
1638
|
-
]
|
|
1639
|
-
}
|
|
1640
|
-
)
|
|
1641
|
-
] }),
|
|
1642
|
-
/* @__PURE__ */ jsx("p", { className: "mb-2 text-sm text-muted-foreground", children: description }),
|
|
1643
|
-
/* @__PURE__ */ jsx(
|
|
1644
|
-
"div",
|
|
1645
|
-
{
|
|
1646
|
-
className: cn(
|
|
1647
|
-
"transition-opacity",
|
|
1648
|
-
!enabled && "pointer-events-none opacity-50",
|
|
1649
|
-
GRID_ACCENT_CLASSES
|
|
1650
|
-
),
|
|
1651
|
-
style: GRID_ACCENT_VARS,
|
|
1652
|
-
"aria-disabled": !enabled,
|
|
1653
|
-
children
|
|
1654
|
-
}
|
|
1655
|
-
)
|
|
1656
|
-
] });
|
|
1657
|
-
}
|
|
1658
|
-
function ModelProviderLabel({ logo, children }) {
|
|
1659
|
-
return /* @__PURE__ */ jsxs("span", { "data-slot": "model-provider", className: "flex items-center gap-1.5", children: [
|
|
1660
|
-
logo,
|
|
1661
|
-
children
|
|
1662
|
-
] });
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
export { ActiveSessionsDialog, AvatarPicker, DEFAULT_ACTIVE_SESSIONS_DIALOG_LABELS, DEFAULT_AVATAR_PICKER_LABELS, DEFAULT_DELETE_ACCOUNT_DIALOG_LABELS, DEFAULT_IDENTITY_VERIFICATION_LABELS, DEFAULT_LOGOUT_DIALOG_LABELS, DEFAULT_PASSWORD_CHANGE_DIALOG_LABELS, DEFAULT_PROFILE_CARD_LABELS, DEFAULT_SETTINGS_DANGER_ZONE_LABELS, DEFAULT_WORK_OFFLINE_LABELS, DeleteAccountDialog, DraggableHeader, EMAIL_NOTIFICATION_CATEGORIES, EMAIL_NOTIFICATION_KEYS, IdentityVerificationCard, IdentityVerificationDialog, LogoutDialog, ModelProviderLabel, NotificationCategoryList, PanelActionsRow, PanelAddButton, PanelFrame, PanelFrameBody, PanelNote, PanelScroll, PanelTitleBar, PasswordChangeDialog, PremiumModelsFrame, ProfileCard, RequireVerified, ServerConnectionButton, SettingsActionRow, SettingsCard, SettingsDangerZone, SettingsPage, SettingsPanel, SettingsRow, SettingsSection, SettingsSwitchGroup, SettingsSwitchRow, WorkOfflineToggle, formatSessionTtl, resolveSettingsSection, serverConnectionView, toActiveSessionViews, toDeleteBlockerViews, toLogoutSessionViews, toNotificationCategories };
|
|
1666
|
-
//# sourceMappingURL=chunk-5YHEHEJT.js.map
|
|
1667
|
-
//# sourceMappingURL=chunk-5YHEHEJT.js.map
|