@strapi-community/plugin-better-auth-dashboard 1.0.0-alpha.9 → 1.0.0-beta.1

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.
@@ -0,0 +1,734 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const designSystem = require("@strapi/design-system");
4
+ const icons = require("@strapi/icons");
5
+ const react = require("react");
6
+ const styled = require("styled-components");
7
+ const index = require("./index-BHfYu0uA.js");
8
+ const admin = require("@strapi/strapi/admin");
9
+ const reactQuery = require("react-query");
10
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
12
+ function ConfirmDialog({
13
+ title,
14
+ message,
15
+ confirmLabel = "Confirm",
16
+ variant = "danger",
17
+ loading = false,
18
+ onConfirm,
19
+ onCancel
20
+ }) {
21
+ return /* @__PURE__ */ jsxRuntime.jsx(
22
+ designSystem.Modal.Root,
23
+ {
24
+ defaultOpen: true,
25
+ onOpenChange: (open) => !open && onCancel(),
26
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
27
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: title }) }),
28
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: message }) }),
29
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
30
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: onCancel, disabled: loading, children: "Cancel" }),
31
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant, loading, onClick: onConfirm, children: confirmLabel })
32
+ ] })
33
+ ] })
34
+ }
35
+ );
36
+ }
37
+ const DASH_CONTEXT_HEADER = "X-Dash-Context";
38
+ const withContext = (ctx, headers) => ({
39
+ headers: {
40
+ ...headers,
41
+ [DASH_CONTEXT_HEADER]: btoa(JSON.stringify(ctx))
42
+ }
43
+ });
44
+ const slideIn = styled.keyframes`
45
+ from { transform: translateX(100%); opacity: 0.6; }
46
+ to { transform: translateX(0); opacity: 1; }
47
+ `;
48
+ const fadeIn = styled.keyframes`
49
+ from { opacity: 0; }
50
+ to { opacity: 1; }
51
+ `;
52
+ const Overlay = styled__default.default.div`
53
+ position: absolute;
54
+ inset: 0;
55
+ background: rgba(33, 33, 52, 0.4);
56
+ animation: ${fadeIn} 180ms ease;
57
+ `;
58
+ const Panel = styled__default.default.div`
59
+ position: absolute;
60
+ top: 0;
61
+ right: 0;
62
+ bottom: 0;
63
+ width: min(760px, 95vw);
64
+ display: flex;
65
+ flex-direction: column;
66
+ background: white;
67
+ box-shadow: -8px 0 40px rgba(33, 33, 52, 0.18);
68
+ animation: ${slideIn} 220ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
69
+ `;
70
+ function Drawer({
71
+ title,
72
+ children,
73
+ footer,
74
+ onClose,
75
+ "data-testid": testId
76
+ }) {
77
+ react.useEffect(() => {
78
+ const prev = document.body.style.overflow;
79
+ document.body.style.overflow = "hidden";
80
+ return () => {
81
+ document.body.style.overflow = prev;
82
+ };
83
+ }, []);
84
+ react.useEffect(() => {
85
+ const handler = (e) => {
86
+ if (e.key === "Escape") onClose();
87
+ };
88
+ document.addEventListener("keydown", handler);
89
+ return () => document.removeEventListener("keydown", handler);
90
+ }, [onClose]);
91
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "fixed", inset: 0, zIndex: 200 }, children: [
92
+ /* @__PURE__ */ jsxRuntime.jsx(Overlay, { onClick: onClose, "aria-hidden": "true" }),
93
+ /* @__PURE__ */ jsxRuntime.jsxs(Panel, { "data-testid": testId, children: [
94
+ /* @__PURE__ */ jsxRuntime.jsxs(
95
+ designSystem.Flex,
96
+ {
97
+ justifyContent: "space-between",
98
+ alignItems: "center",
99
+ paddingTop: 5,
100
+ paddingBottom: 5,
101
+ paddingLeft: 6,
102
+ paddingRight: 6,
103
+ borderColor: "neutral150",
104
+ borderStyle: "solid",
105
+ borderWidth: "0 0 1px 0",
106
+ style: { flexShrink: 0 },
107
+ children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: title }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.IconButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {}) })
110
+ ]
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsxRuntime.jsx(
114
+ designSystem.Box,
115
+ {
116
+ paddingTop: 6,
117
+ paddingBottom: 6,
118
+ paddingLeft: 6,
119
+ paddingRight: 6,
120
+ style: { flex: 1, overflowY: "auto" },
121
+ children
122
+ }
123
+ ),
124
+ footer && /* @__PURE__ */ jsxRuntime.jsx(
125
+ designSystem.Flex,
126
+ {
127
+ justifyContent: "flex-end",
128
+ gap: 2,
129
+ paddingTop: 4,
130
+ paddingBottom: 4,
131
+ paddingLeft: 6,
132
+ paddingRight: 6,
133
+ borderColor: "neutral150",
134
+ borderStyle: "solid",
135
+ borderWidth: "1px 0 0 0",
136
+ style: { flexShrink: 0 },
137
+ children: footer
138
+ }
139
+ )
140
+ ] })
141
+ ] }) });
142
+ }
143
+ const FormSection = styled__default.default.div`
144
+ width: 100%;
145
+ background: #f6f6f9;
146
+ border-radius: 8px;
147
+ padding: 16px 20px;
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: 14px;
151
+ `;
152
+ const EditLayout = styled__default.default.div`
153
+ display: grid;
154
+ grid-template-columns: minmax(0, 1fr) 256px;
155
+ gap: 28px;
156
+ align-items: start;
157
+ padding-top: 24px;
158
+ `;
159
+ const EditSidebar = styled__default.default.div`
160
+ display: flex;
161
+ flex-direction: column;
162
+ gap: 20px;
163
+ position: sticky;
164
+ top: 0;
165
+ `;
166
+ const SectionLabel = styled__default.default.p`
167
+ font-size: 11px;
168
+ font-weight: 700;
169
+ color: #8e8ea9;
170
+ text-transform: uppercase;
171
+ letter-spacing: 0.05em;
172
+ margin: 0 0 4px;
173
+ `;
174
+ styled__default.default.div`
175
+ background: #f6f6f9;
176
+ border-radius: 8px;
177
+ padding: 16px;
178
+ display: grid;
179
+ grid-template-columns: 1fr 1fr;
180
+ gap: 16px;
181
+ `;
182
+ const MetaItem = styled__default.default.div`
183
+ display: flex;
184
+ flex-direction: column;
185
+ gap: 4px;
186
+ `;
187
+ const MetaKey = styled__default.default.span`
188
+ font-size: 11px;
189
+ font-weight: 600;
190
+ color: #8e8ea9;
191
+ text-transform: uppercase;
192
+ letter-spacing: 0.03em;
193
+ `;
194
+ const MetaVal = styled__default.default.span`
195
+ font-size: 13px;
196
+ color: #32324d;
197
+ `;
198
+ const MonoChip = styled__default.default.code`
199
+ display: inline;
200
+ font-size: 11px;
201
+ color: #4945ff;
202
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
203
+ word-break: break-all;
204
+ background: #f0f0ff;
205
+ padding: 2px 6px;
206
+ border-radius: 3px;
207
+ `;
208
+ const ProviderBadge = styled__default.default.span`
209
+ display: inline-flex;
210
+ align-items: center;
211
+ padding: 2px 8px;
212
+ background: #f0f0ff;
213
+ border: 1px solid #d9d8ff;
214
+ border-radius: 4px;
215
+ font-size: 12px;
216
+ font-weight: 600;
217
+ color: #4945ff;
218
+ text-transform: capitalize;
219
+ `;
220
+ const WarnCard = styled__default.default.div`
221
+ background: #fcecea;
222
+ border: 1px solid #f5c0b8;
223
+ border-radius: 8px;
224
+ padding: 14px 16px;
225
+ display: flex;
226
+ flex-direction: column;
227
+ gap: 4px;
228
+ `;
229
+ styled__default.default.div`
230
+ background: #eafbe7;
231
+ border: 1px solid #c6efbd;
232
+ border-radius: 8px;
233
+ padding: 14px 16px;
234
+ `;
235
+ const PreviewPill = styled__default.default.div`
236
+ display: inline-flex;
237
+ align-items: center;
238
+ gap: 6px;
239
+ padding: 6px 12px;
240
+ background: #fff3d3;
241
+ border: 1px solid #f5d97f;
242
+ border-radius: 6px;
243
+ font-size: 12px;
244
+ font-weight: 500;
245
+ color: #8e6a00;
246
+ width: fit-content;
247
+ `;
248
+ const AccountRow = styled__default.default.div`
249
+ width: 100%;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: space-between;
253
+ padding: 10px 14px;
254
+ background: white;
255
+ border: 1px solid #dcdce4;
256
+ border-radius: 8px;
257
+ gap: 12px;
258
+ `;
259
+ const DangerRow = styled__default.default(AccountRow)`
260
+ background: #fef8f8;
261
+ border-color: #f5c0b8;
262
+ `;
263
+ const RoleBadge = styled__default.default.span`
264
+ display: inline-flex;
265
+ align-items: center;
266
+ padding: 2px 8px;
267
+ border-radius: 4px;
268
+ font-size: 11px;
269
+ font-weight: 600;
270
+ text-transform: capitalize;
271
+ background: ${(p) => p.$role === "owner" ? "#f0f0ff" : p.$role === "admin" ? "#eafbe7" : "#f5f5f9"};
272
+ border: 1px solid
273
+ ${(p) => p.$role === "owner" ? "#d9d8ff" : p.$role === "admin" ? "#c6efbd" : "#dcdce4"};
274
+ color: ${(p) => p.$role === "owner" ? "#4945ff" : p.$role === "admin" ? "#2e8044" : "#666687"};
275
+ `;
276
+ function MediaPickerField({
277
+ label,
278
+ value,
279
+ onChange,
280
+ hint,
281
+ placeholder,
282
+ name,
283
+ required
284
+ }) {
285
+ const [showMedia, setShowMedia] = react.useState(false);
286
+ const MediaLibraryDialog = index.getMediaLibraryComponent();
287
+ const handleSelect = (assets) => {
288
+ const asset = assets[0];
289
+ if (!asset) return;
290
+ const url = asset.formats?.small?.url ?? asset.formats?.thumbnail?.url ?? asset.url;
291
+ onChange(url);
292
+ setShowMedia(false);
293
+ };
294
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
295
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: { width: "100%" }, hint, required, children: [
296
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
297
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
298
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
299
+ designSystem.TextInput,
300
+ {
301
+ name,
302
+ type: "url",
303
+ value,
304
+ onChange: (e) => onChange(e.target.value),
305
+ placeholder,
306
+ style: { width: "100%" }
307
+ }
308
+ ) }),
309
+ MediaLibraryDialog && /* @__PURE__ */ jsxRuntime.jsx(
310
+ designSystem.Button,
311
+ {
312
+ variant: "secondary",
313
+ size: "S",
314
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Images, {}),
315
+ onClick: () => setShowMedia(true),
316
+ style: { flexShrink: 0 },
317
+ children: "Browse"
318
+ }
319
+ )
320
+ ] }),
321
+ hint && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
322
+ ] }),
323
+ showMedia && MediaLibraryDialog && /* @__PURE__ */ jsxRuntime.jsx(
324
+ MediaLibraryDialog,
325
+ {
326
+ allowedTypes: ["images"],
327
+ multiple: false,
328
+ onClose: () => setShowMedia(false),
329
+ onSelectAssets: handleSelect
330
+ }
331
+ )
332
+ ] });
333
+ }
334
+ const EntryRow = styled__default.default.div`
335
+ display: flex;
336
+ align-items: center;
337
+ justify-content: space-between;
338
+ gap: 8px;
339
+ padding: 8px 12px;
340
+ width: 100%;
341
+ box-sizing: border-box;
342
+ background: #ffffff;
343
+ border: 1px solid ${({ theme }) => theme.colors?.neutral200 ?? "#dcdce4"};
344
+ border-radius: 4px;
345
+ min-width: 0;
346
+ `;
347
+ function getDisplayLabel(doc) {
348
+ for (const key of ["name", "title", "email", "username", "label", "slug"]) {
349
+ const v = doc[key];
350
+ if (typeof v === "string" && v.trim()) return v;
351
+ }
352
+ return String(doc.documentId ?? doc.id ?? "");
353
+ }
354
+ function normalizeValue(val, cache) {
355
+ if (!val) return [];
356
+ if (typeof val === "object" && !Array.isArray(val) && val !== null && "set" in val) {
357
+ const items2 = val.set ?? [];
358
+ return items2.filter((item) => item?.documentId).map((item) => ({
359
+ documentId: item.documentId,
360
+ label: cache.get(item.documentId) ?? item.documentId
361
+ }));
362
+ }
363
+ const items = Array.isArray(val) ? val : [val];
364
+ return items.filter(
365
+ (item) => typeof item === "object" && item !== null && "documentId" in item
366
+ ).map((item) => ({
367
+ documentId: String(item.documentId),
368
+ label: getDisplayLabel(item)
369
+ }));
370
+ }
371
+ function RelationField({
372
+ name,
373
+ label,
374
+ attribute,
375
+ value,
376
+ onChange,
377
+ readOnly = false
378
+ }) {
379
+ const { get } = admin.useFetchClient();
380
+ const cache = react.useRef(/* @__PURE__ */ new Map());
381
+ const [search, setSearch] = react.useState("");
382
+ const [addKey, setAddKey] = react.useState(0);
383
+ const target = attribute.target ?? "";
384
+ const relationType = attribute.relation ?? "manyToOne";
385
+ const isMulti = relationType === "oneToMany" || relationType === "manyToMany";
386
+ const currentDocs = normalizeValue(value, cache.current);
387
+ const selectedIds = new Set(currentDocs.map((d) => d.documentId));
388
+ const { data: searchResults = [], isLoading } = reactQuery.useQuery({
389
+ queryKey: ["relation-search", target, search],
390
+ queryFn: async () => {
391
+ const params = new URLSearchParams({
392
+ uid: target,
393
+ "pagination[pageSize]": "50"
394
+ });
395
+ if (search) params.set("filters[name][$containsi]", search);
396
+ const { data } = await get(
397
+ `/better-auth-dashboard/db?${params}`
398
+ );
399
+ const docs = data.results ?? [];
400
+ for (const doc of docs) {
401
+ if (doc.documentId) {
402
+ cache.current.set(String(doc.documentId), getDisplayLabel(doc));
403
+ }
404
+ }
405
+ return docs.map((doc) => ({
406
+ documentId: String(doc.documentId ?? ""),
407
+ label: getDisplayLabel(doc)
408
+ })).filter((d) => d.documentId);
409
+ },
410
+ keepPreviousData: true,
411
+ enabled: !readOnly
412
+ });
413
+ const availableOptions = searchResults.filter(
414
+ (r) => !selectedIds.has(r.documentId)
415
+ );
416
+ const commit = (ids) => {
417
+ onChange(name, { set: ids.map((id) => ({ documentId: id })) });
418
+ };
419
+ const handleSelect = (val) => {
420
+ if (!val) return;
421
+ const opt = searchResults.find((r) => r.documentId === val);
422
+ if (opt) cache.current.set(val, opt.label);
423
+ if (isMulti) {
424
+ if (selectedIds.has(val)) return;
425
+ commit([...currentDocs.map((d) => d.documentId), val]);
426
+ } else {
427
+ commit([val]);
428
+ }
429
+ setSearch("");
430
+ setAddKey((k) => k + 1);
431
+ };
432
+ const handleRemove = (docId) => {
433
+ commit(
434
+ currentDocs.filter((d) => d.documentId !== docId).map((d) => d.documentId)
435
+ );
436
+ };
437
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: { width: "100%" }, children: [
438
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
439
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
440
+ designSystem.Combobox,
441
+ {
442
+ value: "",
443
+ onChange: (val) => handleSelect(val),
444
+ onInputChange: (e) => setSearch(e.target.value),
445
+ loading: isLoading,
446
+ placeholder: "Search…",
447
+ children: availableOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: opt.documentId, children: opt.label }, opt.documentId))
448
+ },
449
+ addKey
450
+ ),
451
+ currentDocs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
452
+ designSystem.Flex,
453
+ {
454
+ direction: "column",
455
+ gap: 1,
456
+ style: { marginTop: 8, width: "100%" },
457
+ children: currentDocs.map((doc) => /* @__PURE__ */ jsxRuntime.jsxs(EntryRow, { children: [
458
+ /* @__PURE__ */ jsxRuntime.jsx(
459
+ designSystem.Typography,
460
+ {
461
+ variant: "omega",
462
+ textColor: "neutral800",
463
+ style: {
464
+ overflow: "hidden",
465
+ textOverflow: "ellipsis",
466
+ whiteSpace: "nowrap",
467
+ flex: 1,
468
+ minWidth: 0
469
+ },
470
+ children: doc.label
471
+ }
472
+ ),
473
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
474
+ designSystem.IconButton,
475
+ {
476
+ label: "Remove",
477
+ size: "S",
478
+ onClick: () => handleRemove(doc.documentId),
479
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
480
+ }
481
+ )
482
+ ] }, doc.documentId))
483
+ }
484
+ )
485
+ ] });
486
+ }
487
+ function makeLabel(name) {
488
+ return name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
489
+ }
490
+ const fieldStyle = { width: "100%" };
491
+ function DynamicField({
492
+ field,
493
+ value,
494
+ onChange,
495
+ readOnly = false
496
+ }) {
497
+ const { name, attribute } = field;
498
+ const { type, required, enum: enumValues } = attribute;
499
+ const label = makeLabel(name);
500
+ if (type === "boolean") {
501
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
502
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
503
+ /* @__PURE__ */ jsxRuntime.jsx(
504
+ designSystem.Checkbox,
505
+ {
506
+ checked: Boolean(value),
507
+ onCheckedChange: (checked) => onChange(name, checked),
508
+ disabled: readOnly,
509
+ children: label
510
+ }
511
+ )
512
+ ] });
513
+ }
514
+ if (type === "enumeration" && Array.isArray(enumValues)) {
515
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
516
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
517
+ /* @__PURE__ */ jsxRuntime.jsx(
518
+ designSystem.SingleSelect,
519
+ {
520
+ value: value != null ? String(value) : "",
521
+ onChange: (v) => onChange(name, String(v)),
522
+ disabled: readOnly,
523
+ required,
524
+ placeholder: "—",
525
+ children: enumValues.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: opt, children: opt }, opt))
526
+ }
527
+ )
528
+ ] });
529
+ }
530
+ if (type === "integer" || type === "biginteger" || type === "float" || type === "decimal") {
531
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
532
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
533
+ /* @__PURE__ */ jsxRuntime.jsx(
534
+ designSystem.NumberInput,
535
+ {
536
+ value: value != null ? Number(value) : void 0,
537
+ onValueChange: (v) => onChange(name, v),
538
+ disabled: readOnly,
539
+ required
540
+ }
541
+ )
542
+ ] });
543
+ }
544
+ if (type === "json") {
545
+ const jsonStr = value == null ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
546
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
548
+ /* @__PURE__ */ jsxRuntime.jsx(
549
+ designSystem.JSONInput,
550
+ {
551
+ value: jsonStr,
552
+ onChange: (v) => {
553
+ try {
554
+ onChange(name, JSON.parse(v));
555
+ } catch {
556
+ onChange(name, v);
557
+ }
558
+ },
559
+ disabled: readOnly
560
+ }
561
+ )
562
+ ] });
563
+ }
564
+ if (type === "date") {
565
+ const dateStr = value instanceof Date ? value.toISOString().slice(0, 10) : typeof value === "string" ? value.slice(0, 10) : "";
566
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
567
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
568
+ /* @__PURE__ */ jsxRuntime.jsx(
569
+ designSystem.TextInput,
570
+ {
571
+ type: "date",
572
+ value: dateStr,
573
+ onChange: (e) => onChange(name, e.target.value),
574
+ disabled: readOnly,
575
+ required
576
+ }
577
+ )
578
+ ] });
579
+ }
580
+ if (type === "datetime" || type === "timestamp") {
581
+ const dtStr = value instanceof Date ? value.toISOString().slice(0, 16) : typeof value === "string" ? value.slice(0, 16) : "";
582
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
583
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
584
+ /* @__PURE__ */ jsxRuntime.jsx(
585
+ designSystem.TextInput,
586
+ {
587
+ type: "datetime-local",
588
+ value: dtStr,
589
+ onChange: (e) => onChange(name, e.target.value),
590
+ disabled: readOnly,
591
+ required
592
+ }
593
+ )
594
+ ] });
595
+ }
596
+ if (type === "text" || type === "richtext") {
597
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
598
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
599
+ /* @__PURE__ */ jsxRuntime.jsx(
600
+ designSystem.Textarea,
601
+ {
602
+ value: value != null ? String(value) : "",
603
+ onChange: (e) => onChange(name, e.target.value),
604
+ disabled: readOnly
605
+ }
606
+ )
607
+ ] });
608
+ }
609
+ if (type === "relation") {
610
+ return /* @__PURE__ */ jsxRuntime.jsx(
611
+ RelationField,
612
+ {
613
+ name,
614
+ label,
615
+ attribute,
616
+ value,
617
+ onChange,
618
+ readOnly
619
+ }
620
+ );
621
+ }
622
+ const inputType = type === "email" ? "email" : type === "password" ? "password" : type === "time" ? "time" : "text";
623
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { style: fieldStyle, children: [
624
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
625
+ /* @__PURE__ */ jsxRuntime.jsx(
626
+ designSystem.TextInput,
627
+ {
628
+ type: inputType,
629
+ value: value != null ? String(value) : "",
630
+ onChange: (e) => onChange(name, e.target.value),
631
+ disabled: readOnly,
632
+ required
633
+ }
634
+ )
635
+ ] });
636
+ }
637
+ const SKIP_TYPES = /* @__PURE__ */ new Set(["media", "dynamiczone", "blocks", "component"]);
638
+ function CustomFieldsSection({
639
+ fields,
640
+ data,
641
+ onChange
642
+ }) {
643
+ const renderable = fields.filter((f) => !SKIP_TYPES.has(f.attribute.type));
644
+ if (renderable.length === 0) return null;
645
+ return /* @__PURE__ */ jsxRuntime.jsxs(FormSection, { children: [
646
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Custom fields" }),
647
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 4, alignItems: "stretch", children: renderable.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
648
+ DynamicField,
649
+ {
650
+ field,
651
+ value: data[field.name],
652
+ onChange
653
+ },
654
+ field.name
655
+ )) })
656
+ ] });
657
+ }
658
+ function EditViewSidePanels({ model, documentId, document: document2 }) {
659
+ const panels = index.getEditViewSidePanels(model);
660
+ if (panels.length === 0) return null;
661
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: panels.map(({ id, title, Component }) => /* @__PURE__ */ jsxRuntime.jsxs(FormSection, { children: [
662
+ /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: title }),
663
+ /* @__PURE__ */ jsxRuntime.jsx(
664
+ Component,
665
+ {
666
+ model,
667
+ documentId,
668
+ document: document2
669
+ }
670
+ )
671
+ ] }, id)) });
672
+ }
673
+ const SYSTEM_FIELDS = /* @__PURE__ */ new Set([
674
+ "id",
675
+ "documentId",
676
+ "createdAt",
677
+ "updatedAt",
678
+ "publishedAt",
679
+ "createdBy",
680
+ "updatedBy",
681
+ "locale",
682
+ "localizations"
683
+ ]);
684
+ const MODEL_UID = {
685
+ user: "plugin::better-auth.user",
686
+ organization: "plugin::better-auth.organization"
687
+ };
688
+ function useModelSchema(model) {
689
+ const { get } = admin.useFetchClient();
690
+ return reactQuery.useQuery({
691
+ queryKey: ["ba-model-schema", model],
692
+ queryFn: async () => {
693
+ const { data } = await get(
694
+ "/content-manager/content-types"
695
+ );
696
+ const uid = MODEL_UID[model];
697
+ const contentType = data.data.find((ct) => ct.uid === uid);
698
+ if (!contentType) throw new Error(`Content type ${uid} not found`);
699
+ const attributes = {};
700
+ for (const [name, attr] of Object.entries(contentType.attributes)) {
701
+ if (SYSTEM_FIELDS.has(name)) continue;
702
+ if (attr.type === "relation" && typeof attr.target === "string" && (attr.target.startsWith("plugin::users-permissions") || attr.target.startsWith("admin::")))
703
+ continue;
704
+ const baOptions = attr.pluginOptions?.["better-auth"];
705
+ if (baOptions?.managed === true) continue;
706
+ attributes[name] = attr;
707
+ }
708
+ return attributes;
709
+ },
710
+ staleTime: 10 * 60 * 1e3,
711
+ retry: false
712
+ });
713
+ }
714
+ exports.AccountRow = AccountRow;
715
+ exports.ConfirmDialog = ConfirmDialog;
716
+ exports.CustomFieldsSection = CustomFieldsSection;
717
+ exports.DangerRow = DangerRow;
718
+ exports.Drawer = Drawer;
719
+ exports.EditLayout = EditLayout;
720
+ exports.EditSidebar = EditSidebar;
721
+ exports.EditViewSidePanels = EditViewSidePanels;
722
+ exports.FormSection = FormSection;
723
+ exports.MediaPickerField = MediaPickerField;
724
+ exports.MetaItem = MetaItem;
725
+ exports.MetaKey = MetaKey;
726
+ exports.MetaVal = MetaVal;
727
+ exports.MonoChip = MonoChip;
728
+ exports.PreviewPill = PreviewPill;
729
+ exports.ProviderBadge = ProviderBadge;
730
+ exports.RoleBadge = RoleBadge;
731
+ exports.SectionLabel = SectionLabel;
732
+ exports.WarnCard = WarnCard;
733
+ exports.useModelSchema = useModelSchema;
734
+ exports.withContext = withContext;