@brokr/sdk 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react-notifications.js +63 -50
- package/dist/react-notifications.mjs +63 -50
- package/dist/react-styles.js +113 -75
- package/dist/react-styles.mjs +113 -75
- package/dist/react-theme.js +6 -4
- package/dist/react-theme.mjs +6 -4
- package/dist/react.js +325 -246
- package/dist/react.mjs +360 -281
- package/dist/src/react/account/AccountPanel.d.ts.map +1 -1
- package/dist/src/react/account/UserButton.d.ts.map +1 -1
- package/dist/src/react/chat/AIChat.d.ts.map +1 -1
- package/dist/src/react/chat/ChatInput.d.ts.map +1 -1
- package/dist/src/react/chat/MessagePane.d.ts.map +1 -1
- package/dist/src/react/chat/ModelSelector.d.ts.map +1 -1
- package/dist/src/react/chat/ThreadSidebar.d.ts.map +1 -1
- package/dist/src/react/composites/FabAI.d.ts.map +1 -1
- package/dist/src/react/css/account.d.ts +1 -1
- package/dist/src/react/css/account.d.ts.map +1 -1
- package/dist/src/react/css/auth.d.ts +1 -1
- package/dist/src/react/css/auth.d.ts.map +1 -1
- package/dist/src/react/css/chat-extras.d.ts +1 -1
- package/dist/src/react/css/chat-extras.d.ts.map +1 -1
- package/dist/src/react/css/chat.d.ts +1 -1
- package/dist/src/react/css/chat.d.ts.map +1 -1
- package/dist/src/react/css/composites.d.ts +1 -1
- package/dist/src/react/css/composites.d.ts.map +1 -1
- package/dist/src/react/css/markdown.d.ts +1 -1
- package/dist/src/react/css/markdown.d.ts.map +1 -1
- package/dist/src/react/css/notifications.d.ts +1 -1
- package/dist/src/react/css/notifications.d.ts.map +1 -1
- package/dist/src/react/css/tokens.d.ts +1 -1
- package/dist/src/react/css/tokens.d.ts.map +1 -1
- package/dist/src/react/notifications/NotificationBell.d.ts.map +1 -1
- package/dist/src/react/notifications/NotificationList.d.ts.map +1 -1
- package/dist/src/react/notifications/Toast.d.ts.map +1 -1
- package/dist/src/react/payments/Plans.d.ts.map +1 -1
- package/dist/src/react/theme.d.ts.map +1 -1
- package/dist/src/react/types.d.ts +4 -4
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -4237,10 +4237,12 @@ function getBrokrRootStyle(theme) {
|
|
|
4237
4237
|
...theme.colors.error ? { ["--brokr-error"]: theme.colors.error } : {},
|
|
4238
4238
|
...theme.colors.success ? { ["--brokr-success"]: theme.colors.success } : {},
|
|
4239
4239
|
...theme.colors.warning ? { ["--brokr-warning"]: theme.colors.warning } : {},
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4240
|
+
// Toast vars always emitted with smart defaults — toasts stay light in dark mode.
|
|
4241
|
+
// Users can override via theme.colors.toastBg etc.
|
|
4242
|
+
["--brokr-toast-bg"]: theme.colors.toastBg ?? "#ffffff",
|
|
4243
|
+
["--brokr-toast-text"]: theme.colors.toastText ?? "#0a0a0a",
|
|
4244
|
+
["--brokr-toast-text-secondary"]: theme.colors.toastTextSecondary ?? "#52525b",
|
|
4245
|
+
["--brokr-toast-border"]: theme.colors.toastBorder ?? "#e4e4e7",
|
|
4244
4246
|
["--brokr-radius-card"]: `${theme.radii.card}px`,
|
|
4245
4247
|
["--brokr-radius-input"]: `${theme.radii.input}px`,
|
|
4246
4248
|
["--brokr-radius-button"]: `${theme.radii.button}px`
|
|
@@ -4355,6 +4357,37 @@ function resolveNotificationType(registry, type, data) {
|
|
|
4355
4357
|
|
|
4356
4358
|
// src/react/notifications/Toast.tsx
|
|
4357
4359
|
var import_react2 = __toESM(require("react"));
|
|
4360
|
+
function ToastItem({
|
|
4361
|
+
notification,
|
|
4362
|
+
exiting,
|
|
4363
|
+
registry,
|
|
4364
|
+
onDismiss
|
|
4365
|
+
}) {
|
|
4366
|
+
const handleDismiss = (0, import_react2.useCallback)(() => onDismiss(notification.id), [notification.id, onDismiss]);
|
|
4367
|
+
const notifData = notification.data ?? {};
|
|
4368
|
+
const notifType = notifData.type ?? "default";
|
|
4369
|
+
const resolved = resolveNotificationType(registry, notifType, notifData);
|
|
4370
|
+
return /* @__PURE__ */ import_react2.default.createElement(
|
|
4371
|
+
"div",
|
|
4372
|
+
{
|
|
4373
|
+
className: `brokr-toast brokr-toast--${notification.variant}${exiting ? " brokr-toast--exit" : ""}`,
|
|
4374
|
+
role: "alert",
|
|
4375
|
+
"aria-live": "polite"
|
|
4376
|
+
},
|
|
4377
|
+
resolved.image ? /* @__PURE__ */ import_react2.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-toast-provider-logo" }) : /* @__PURE__ */ import_react2.default.createElement("span", { className: `brokr-toast-icon brokr-toast-icon--${notification.variant}` }),
|
|
4378
|
+
/* @__PURE__ */ import_react2.default.createElement("div", { className: "brokr-toast-content" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-title" }, notification.title), /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-message" }, notification.message)),
|
|
4379
|
+
/* @__PURE__ */ import_react2.default.createElement(
|
|
4380
|
+
"button",
|
|
4381
|
+
{
|
|
4382
|
+
type: "button",
|
|
4383
|
+
className: "brokr-toast-dismiss",
|
|
4384
|
+
onClick: handleDismiss,
|
|
4385
|
+
"aria-label": "Dismiss notification"
|
|
4386
|
+
},
|
|
4387
|
+
/* @__PURE__ */ import_react2.default.createElement("svg", { "aria-hidden": "true", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M18 6 6 18M6 6l12 12" }))
|
|
4388
|
+
)
|
|
4389
|
+
);
|
|
4390
|
+
}
|
|
4358
4391
|
var DEFAULT_DURATION = 4e3;
|
|
4359
4392
|
var DEFAULT_MAX_VISIBLE = 3;
|
|
4360
4393
|
var EXIT_ANIMATION_MS = 300;
|
|
@@ -4365,6 +4398,26 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
|
|
|
4365
4398
|
const duration = config.toast?.duration ?? DEFAULT_DURATION;
|
|
4366
4399
|
const maxVisible = config.toast?.maxVisible ?? DEFAULT_MAX_VISIBLE;
|
|
4367
4400
|
const position = config.toast?.position ?? "top-right";
|
|
4401
|
+
const onDismissRef = (0, import_react2.useRef)(onDismiss);
|
|
4402
|
+
onDismissRef.current = onDismiss;
|
|
4403
|
+
const exitingRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
4404
|
+
const dismissToast = (0, import_react2.useCallback)((id) => {
|
|
4405
|
+
if (exitingRef.current.has(id)) return;
|
|
4406
|
+
exitingRef.current.add(id);
|
|
4407
|
+
setEntries(
|
|
4408
|
+
(prev) => prev.map((e) => e.notification.id === id ? { ...e, exiting: true } : e)
|
|
4409
|
+
);
|
|
4410
|
+
setTimeout(() => {
|
|
4411
|
+
setEntries((prev) => prev.filter((e) => e.notification.id !== id));
|
|
4412
|
+
onDismissRef.current(id);
|
|
4413
|
+
exitingRef.current.delete(id);
|
|
4414
|
+
}, EXIT_ANIMATION_MS);
|
|
4415
|
+
const timer = timersRef.current.get(id);
|
|
4416
|
+
if (timer) {
|
|
4417
|
+
clearTimeout(timer);
|
|
4418
|
+
timersRef.current.delete(id);
|
|
4419
|
+
}
|
|
4420
|
+
}, []);
|
|
4368
4421
|
(0, import_react2.useEffect)(() => {
|
|
4369
4422
|
for (const toast of toasts) {
|
|
4370
4423
|
if (processedRef.current.has(toast.id)) continue;
|
|
@@ -4383,21 +4436,7 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
|
|
|
4383
4436
|
timersRef.current.set(toast.id, timer);
|
|
4384
4437
|
}
|
|
4385
4438
|
}
|
|
4386
|
-
}, [toasts, duration, maxVisible]);
|
|
4387
|
-
const dismissToast = (0, import_react2.useCallback)((id) => {
|
|
4388
|
-
setEntries(
|
|
4389
|
-
(prev) => prev.map((e) => e.notification.id === id ? { ...e, exiting: true } : e)
|
|
4390
|
-
);
|
|
4391
|
-
setTimeout(() => {
|
|
4392
|
-
setEntries((prev) => prev.filter((e) => e.notification.id !== id));
|
|
4393
|
-
onDismiss(id);
|
|
4394
|
-
}, EXIT_ANIMATION_MS);
|
|
4395
|
-
const timer = timersRef.current.get(id);
|
|
4396
|
-
if (timer) {
|
|
4397
|
-
clearTimeout(timer);
|
|
4398
|
-
timersRef.current.delete(id);
|
|
4399
|
-
}
|
|
4400
|
-
}, [onDismiss]);
|
|
4439
|
+
}, [toasts, duration, maxVisible, dismissToast]);
|
|
4401
4440
|
(0, import_react2.useEffect)(() => {
|
|
4402
4441
|
return () => {
|
|
4403
4442
|
for (const timer of timersRef.current.values()) {
|
|
@@ -4417,39 +4456,16 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
|
|
|
4417
4456
|
return map[position] ?? "brokr-toast-layer--bottom-right";
|
|
4418
4457
|
}, [position]);
|
|
4419
4458
|
if (entries.length === 0) return null;
|
|
4420
|
-
return /* @__PURE__ */ import_react2.default.createElement("div", { className: `brokr-toast-layer ${positionClass}` }, entries.map(({ notification, exiting }) =>
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
"aria-live": "polite"
|
|
4431
|
-
},
|
|
4432
|
-
resolved.image ? /* @__PURE__ */ import_react2.default.createElement(
|
|
4433
|
-
"img",
|
|
4434
|
-
{
|
|
4435
|
-
src: resolved.image.url,
|
|
4436
|
-
alt: resolved.image.alt,
|
|
4437
|
-
className: "brokr-toast-provider-logo"
|
|
4438
|
-
}
|
|
4439
|
-
) : /* @__PURE__ */ import_react2.default.createElement("span", { className: `brokr-toast-icon brokr-toast-icon--${notification.variant}` }),
|
|
4440
|
-
/* @__PURE__ */ import_react2.default.createElement("div", { className: "brokr-toast-content" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-title" }, notification.title), /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-message" }, notification.message)),
|
|
4441
|
-
/* @__PURE__ */ import_react2.default.createElement(
|
|
4442
|
-
"button",
|
|
4443
|
-
{
|
|
4444
|
-
type: "button",
|
|
4445
|
-
className: "brokr-toast-dismiss",
|
|
4446
|
-
onClick: () => dismissToast(notification.id),
|
|
4447
|
-
"aria-label": "Dismiss notification"
|
|
4448
|
-
},
|
|
4449
|
-
/* @__PURE__ */ import_react2.default.createElement("svg", { "aria-hidden": "true", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M18 6 6 18M6 6l12 12" }))
|
|
4450
|
-
)
|
|
4451
|
-
);
|
|
4452
|
-
}));
|
|
4459
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", { className: `brokr-toast-layer ${positionClass}` }, entries.map(({ notification, exiting }) => /* @__PURE__ */ import_react2.default.createElement(
|
|
4460
|
+
ToastItem,
|
|
4461
|
+
{
|
|
4462
|
+
key: notification.id,
|
|
4463
|
+
notification,
|
|
4464
|
+
exiting,
|
|
4465
|
+
registry,
|
|
4466
|
+
onDismiss: dismissToast
|
|
4467
|
+
}
|
|
4468
|
+
)));
|
|
4453
4469
|
}
|
|
4454
4470
|
|
|
4455
4471
|
// src/react/notifications/provider.tsx
|
|
@@ -5565,6 +5581,26 @@ function filterDefined(defaults, overrides) {
|
|
|
5565
5581
|
}
|
|
5566
5582
|
|
|
5567
5583
|
// src/react/account/AccountPanel.tsx
|
|
5584
|
+
function AccountTabButton({
|
|
5585
|
+
tab,
|
|
5586
|
+
active,
|
|
5587
|
+
icon,
|
|
5588
|
+
label,
|
|
5589
|
+
onSelect
|
|
5590
|
+
}) {
|
|
5591
|
+
const handleClick = (0, import_react11.useCallback)(() => onSelect(tab), [tab, onSelect]);
|
|
5592
|
+
return /* @__PURE__ */ import_react11.default.createElement(
|
|
5593
|
+
"button",
|
|
5594
|
+
{
|
|
5595
|
+
className: "brokr-account-tab",
|
|
5596
|
+
"data-active": active,
|
|
5597
|
+
onClick: handleClick,
|
|
5598
|
+
type: "button"
|
|
5599
|
+
},
|
|
5600
|
+
/* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-tab-icon" }, icon),
|
|
5601
|
+
/* @__PURE__ */ import_react11.default.createElement("span", null, label)
|
|
5602
|
+
);
|
|
5603
|
+
}
|
|
5568
5604
|
var TAB_META = {
|
|
5569
5605
|
general: {
|
|
5570
5606
|
label: "General"
|
|
@@ -5696,16 +5732,15 @@ function AccountPanel(inlineProps) {
|
|
|
5696
5732
|
}
|
|
5697
5733
|
}, []);
|
|
5698
5734
|
return /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-panel", "data-density": density }, /* @__PURE__ */ import_react11.default.createElement("aside", { className: "brokr-account-sidebar" }, groupedTabs.map((group) => /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-sidebar-group", key: group.label }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-sidebar-kicker" }, group.label), /* @__PURE__ */ import_react11.default.createElement("nav", { className: "brokr-account-tab-list", "aria-label": `${group.label} settings` }, group.tabs.map((tab) => /* @__PURE__ */ import_react11.default.createElement(
|
|
5699
|
-
|
|
5735
|
+
AccountTabButton,
|
|
5700
5736
|
{
|
|
5701
|
-
className: "brokr-account-tab",
|
|
5702
|
-
"data-active": activeTab === tab,
|
|
5703
5737
|
key: tab,
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5738
|
+
tab,
|
|
5739
|
+
active: activeTab === tab,
|
|
5740
|
+
icon: getTabIcon(tab),
|
|
5741
|
+
label: TAB_META[tab].label,
|
|
5742
|
+
onSelect: setActiveTab
|
|
5743
|
+
}
|
|
5709
5744
|
)))))), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-surface" }, /* @__PURE__ */ import_react11.default.createElement("header", { className: "brokr-account-surface-header" }, /* @__PURE__ */ import_react11.default.createElement("h2", { className: "brokr-title" }, activeTabMeta.label)), activeTab === "general" ? /* @__PURE__ */ import_react11.default.createElement("form", { className: "brokr-account-form", onSubmit: handleSaveProfile }, /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-card" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-photo-row" }, /* @__PURE__ */ import_react11.default.createElement(ProfilePhotoButton, { size: 88 }), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-photo-copy" }, /* @__PURE__ */ import_react11.default.createElement("strong", null, "Profile photo"), /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-copy" }, "PNG, JPEG, and GIF under 10MB"), /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-photo-hint" }, /* @__PURE__ */ import_react11.default.createElement(UploadIcon, { size: 14 }), "Upload new picture")))), /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-card brokr-account-field-list" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-row" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-head" }, /* @__PURE__ */ import_react11.default.createElement("label", { className: "brokr-label", htmlFor: "brokr-account-name" }, "Name")), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-body" }, /* @__PURE__ */ import_react11.default.createElement(
|
|
5710
5745
|
"input",
|
|
5711
5746
|
{
|
|
@@ -5807,6 +5842,9 @@ function UserButton({
|
|
|
5807
5842
|
setOpen(false);
|
|
5808
5843
|
await signOut();
|
|
5809
5844
|
}, [signOut]);
|
|
5845
|
+
const stopPropagation = (0, import_react13.useCallback)((event) => {
|
|
5846
|
+
event.stopPropagation();
|
|
5847
|
+
}, []);
|
|
5810
5848
|
(0, import_react13.useEffect)(() => {
|
|
5811
5849
|
if (!open) return void 0;
|
|
5812
5850
|
const handlePointerDown = (event) => {
|
|
@@ -5840,13 +5878,13 @@ function UserButton({
|
|
|
5840
5878
|
"data-align": align,
|
|
5841
5879
|
role: "dialog"
|
|
5842
5880
|
},
|
|
5843
|
-
/* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-header" }, /* @__PURE__ */ import_react13.default.createElement(Avatar, { email: summary.email, name: summary.name, src: user.image, size: 44 }), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-copy" }, /* @__PURE__ */ import_react13.default.createElement("strong", null, summary.name), /* @__PURE__ */ import_react13.default.createElement("span", null, summary.email))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-actions" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: openSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(SettingsIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Settings")), /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick:
|
|
5881
|
+
/* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-header" }, /* @__PURE__ */ import_react13.default.createElement(Avatar, { email: summary.email, name: summary.name, src: user.image, size: 44 }), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-copy" }, /* @__PURE__ */ import_react13.default.createElement("strong", null, summary.name), /* @__PURE__ */ import_react13.default.createElement("span", null, summary.email))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-actions" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: openSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(SettingsIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Settings")), /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: handleSignOut, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(LogoutIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Sign out"))))
|
|
5844
5882
|
) : null, settingsOpen ? /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-modal-backdrop", role: "presentation", onClick: closeSettings }, /* @__PURE__ */ import_react13.default.createElement(
|
|
5845
5883
|
"div",
|
|
5846
5884
|
{
|
|
5847
5885
|
"aria-modal": "true",
|
|
5848
5886
|
className: "brokr-panel brokr-modal-dialog brokr-account-settings-dialog",
|
|
5849
|
-
onClick:
|
|
5887
|
+
onClick: stopPropagation,
|
|
5850
5888
|
role: "dialog"
|
|
5851
5889
|
},
|
|
5852
5890
|
/* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-modal-toolbar" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-button-ghost", onClick: closeSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement(CloseIcon, { size: 16 }))),
|
|
@@ -6042,6 +6080,28 @@ function AuthWall({ children }) {
|
|
|
6042
6080
|
|
|
6043
6081
|
// src/react/payments/Plans.tsx
|
|
6044
6082
|
var import_react22 = __toESM(require("react"));
|
|
6083
|
+
function PlanCard({
|
|
6084
|
+
plan,
|
|
6085
|
+
highlight,
|
|
6086
|
+
isPending,
|
|
6087
|
+
onSelect
|
|
6088
|
+
}) {
|
|
6089
|
+
const isHighlighted = highlight === plan.slug;
|
|
6090
|
+
const features = Object.entries(plan.features);
|
|
6091
|
+
const handleClick = (0, import_react22.useCallback)(() => {
|
|
6092
|
+
void onSelect(plan.slug);
|
|
6093
|
+
}, [plan.slug, onSelect]);
|
|
6094
|
+
return /* @__PURE__ */ import_react22.default.createElement("article", { className: "brokr-card brokr-plan-card", "data-highlight": isHighlighted, key: plan.slug }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-3)" } }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react22.default.createElement("strong", null, plan.name), plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Current") : null, isHighlighted && !plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Recommended") : null), /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-plan-price" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-plan-value" }, plan.price === 0 ? "$0" : `$${(plan.price / 100).toFixed(0)}`), /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, "/", plan.interval)), plan.trialDays ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, plan.trialDays, " day trial included.") : null), /* @__PURE__ */ import_react22.default.createElement(
|
|
6095
|
+
"button",
|
|
6096
|
+
{
|
|
6097
|
+
className: plan.isCurrent ? "brokr-button-secondary" : "brokr-button",
|
|
6098
|
+
disabled: plan.isCurrent || isPending,
|
|
6099
|
+
onClick: handleClick,
|
|
6100
|
+
type: "button"
|
|
6101
|
+
},
|
|
6102
|
+
plan.isCurrent ? "Current plan" : isPending ? "Redirecting" : "Choose plan"
|
|
6103
|
+
), /* @__PURE__ */ import_react22.default.createElement("ul", { className: "brokr-feature-list" }, features.map(([key, value]) => /* @__PURE__ */ import_react22.default.createElement("li", { className: "brokr-feature-item", key }, /* @__PURE__ */ import_react22.default.createElement(CheckIcon, { size: 14 }), /* @__PURE__ */ import_react22.default.createElement("span", null, featureLabel(key), " \xB7 ", featureValueLabel(value))))));
|
|
6104
|
+
}
|
|
6045
6105
|
function Plans({
|
|
6046
6106
|
columns,
|
|
6047
6107
|
highlight,
|
|
@@ -6072,34 +6132,16 @@ function Plans({
|
|
|
6072
6132
|
setPendingPlan(null);
|
|
6073
6133
|
}
|
|
6074
6134
|
}, [checkout, onSelect]);
|
|
6075
|
-
return /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section" }, paymentsMode === "sandbox" ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message" }, "Sandbox mode \u2014 test cards only.") : null, error ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-grid-auto", style: layoutStyle }, plans.map((plan) =>
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
className: "brokr-card brokr-plan-card",
|
|
6086
|
-
"data-highlight": isHighlighted,
|
|
6087
|
-
key: plan.slug
|
|
6088
|
-
},
|
|
6089
|
-
/* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section", style: { gap: "0.75rem" } }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react22.default.createElement("strong", null, plan.name), plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Current") : null, isHighlighted && !plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Recommended") : null), /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-plan-price" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-plan-value" }, plan.price === 0 ? "$0" : `$${(plan.price / 100).toFixed(0)}`), /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, "/", plan.interval)), plan.trialDays ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, plan.trialDays, " day trial included.") : null),
|
|
6090
|
-
/* @__PURE__ */ import_react22.default.createElement(
|
|
6091
|
-
"button",
|
|
6092
|
-
{
|
|
6093
|
-
className: plan.isCurrent ? "brokr-button-secondary" : "brokr-button",
|
|
6094
|
-
disabled: plan.isCurrent || isPending,
|
|
6095
|
-
onClick: handleClick,
|
|
6096
|
-
type: "button"
|
|
6097
|
-
},
|
|
6098
|
-
plan.isCurrent ? "Current plan" : isPending ? "Redirecting" : "Choose plan"
|
|
6099
|
-
),
|
|
6100
|
-
/* @__PURE__ */ import_react22.default.createElement("ul", { className: "brokr-feature-list" }, features.map(([key, value]) => /* @__PURE__ */ import_react22.default.createElement("li", { className: "brokr-feature-item", key }, /* @__PURE__ */ import_react22.default.createElement(CheckIcon, { size: 14 }), /* @__PURE__ */ import_react22.default.createElement("span", null, featureLabel(key), " \xB7 ", featureValueLabel(value)))))
|
|
6101
|
-
);
|
|
6102
|
-
})));
|
|
6135
|
+
return /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section" }, paymentsMode === "sandbox" ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message" }, "Sandbox mode \u2014 test cards only.") : null, error ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-grid-auto", style: layoutStyle }, plans.map((plan) => /* @__PURE__ */ import_react22.default.createElement(
|
|
6136
|
+
PlanCard,
|
|
6137
|
+
{
|
|
6138
|
+
key: plan.slug,
|
|
6139
|
+
plan,
|
|
6140
|
+
highlight,
|
|
6141
|
+
isPending: pendingPlan === plan.slug,
|
|
6142
|
+
onSelect: handleSelect
|
|
6143
|
+
}
|
|
6144
|
+
))));
|
|
6103
6145
|
}
|
|
6104
6146
|
|
|
6105
6147
|
// src/react/payments/FeatureMeter.tsx
|
|
@@ -6237,7 +6279,7 @@ function AutoReloadToggle({ onChange }) {
|
|
|
6237
6279
|
setIsPending(false);
|
|
6238
6280
|
}
|
|
6239
6281
|
}, [enabled, onChange]);
|
|
6240
|
-
return /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-card brokr-gate-card" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-section", style: { gap: "
|
|
6282
|
+
return /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-card brokr-gate-card" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react27.default.createElement("strong", null, "Auto reload"), /* @__PURE__ */ import_react27.default.createElement("span", { className: "brokr-copy" }, helperText)), /* @__PURE__ */ import_react27.default.createElement(
|
|
6241
6283
|
"button",
|
|
6242
6284
|
{
|
|
6243
6285
|
className: "brokr-button-secondary",
|
|
@@ -6927,6 +6969,37 @@ function useChat(config) {
|
|
|
6927
6969
|
|
|
6928
6970
|
// src/react/chat/ModelSelector.tsx
|
|
6929
6971
|
var import_react32 = __toESM(require("react"));
|
|
6972
|
+
function ModelOption({
|
|
6973
|
+
provider,
|
|
6974
|
+
isActive,
|
|
6975
|
+
isLocked,
|
|
6976
|
+
onSelect,
|
|
6977
|
+
onCheckout
|
|
6978
|
+
}) {
|
|
6979
|
+
const handleClick = (0, import_react32.useCallback)(() => {
|
|
6980
|
+
if (isLocked) {
|
|
6981
|
+
void onCheckout({ plan: "pro" });
|
|
6982
|
+
} else {
|
|
6983
|
+
onSelect(provider.model);
|
|
6984
|
+
}
|
|
6985
|
+
}, [isLocked, onCheckout, onSelect, provider.model]);
|
|
6986
|
+
return /* @__PURE__ */ import_react32.default.createElement(
|
|
6987
|
+
"button",
|
|
6988
|
+
{
|
|
6989
|
+
"aria-selected": isActive,
|
|
6990
|
+
className: "brokr-model-option",
|
|
6991
|
+
"data-active": isActive,
|
|
6992
|
+
"data-locked": isLocked,
|
|
6993
|
+
disabled: isLocked,
|
|
6994
|
+
onClick: handleClick,
|
|
6995
|
+
title: isLocked ? "Add credits to unlock" : void 0,
|
|
6996
|
+
type: "button"
|
|
6997
|
+
},
|
|
6998
|
+
/* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: provider.logo }),
|
|
6999
|
+
/* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-option-label" }, provider.label),
|
|
7000
|
+
isLocked ? /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-lock", "aria-hidden": "true" }, /* @__PURE__ */ import_react32.default.createElement(LockIcon, { size: 13 })) : null
|
|
7001
|
+
);
|
|
7002
|
+
}
|
|
6930
7003
|
function ModelSelector({
|
|
6931
7004
|
activeModel,
|
|
6932
7005
|
setSelectedModel,
|
|
@@ -6939,6 +7012,10 @@ function ModelSelector({
|
|
|
6939
7012
|
() => providers.find((p) => p.model === activeModel) ?? providers[0],
|
|
6940
7013
|
[activeModel]
|
|
6941
7014
|
);
|
|
7015
|
+
const handleModelSelect = (0, import_react32.useCallback)((model) => {
|
|
7016
|
+
setSelectedModel(model);
|
|
7017
|
+
setSelectorOpen(false);
|
|
7018
|
+
}, [setSelectedModel]);
|
|
6942
7019
|
(0, import_react32.useEffect)(() => {
|
|
6943
7020
|
if (!selectorOpen) return;
|
|
6944
7021
|
const onMouseDown = (e) => {
|
|
@@ -6969,37 +7046,34 @@ function ModelSelector({
|
|
|
6969
7046
|
activeProvider ? /* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: activeProvider.logo }) : /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-dot", style: { background: "currentColor" } }),
|
|
6970
7047
|
activeProvider?.label ?? "Model",
|
|
6971
7048
|
/* @__PURE__ */ import_react32.default.createElement(ChevronDownIcon, { size: 13 })
|
|
6972
|
-
), selectorOpen ? /* @__PURE__ */ import_react32.default.createElement("div", { className: "brokr-model-dropdown", role: "listbox" }, providers.map((p) =>
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
onClick: () => {
|
|
6984
|
-
if (locked) {
|
|
6985
|
-
void checkout({ plan: "pro" });
|
|
6986
|
-
} else {
|
|
6987
|
-
setSelectedModel(p.model);
|
|
6988
|
-
setSelectorOpen(false);
|
|
6989
|
-
}
|
|
6990
|
-
},
|
|
6991
|
-
title: locked ? "Add credits to unlock" : void 0,
|
|
6992
|
-
type: "button"
|
|
6993
|
-
},
|
|
6994
|
-
/* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: p.logo }),
|
|
6995
|
-
/* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-option-label" }, p.label),
|
|
6996
|
-
locked ? /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-lock", "aria-hidden": "true" }, /* @__PURE__ */ import_react32.default.createElement(LockIcon, { size: 13 })) : null
|
|
6997
|
-
);
|
|
6998
|
-
})) : null);
|
|
7049
|
+
), selectorOpen ? /* @__PURE__ */ import_react32.default.createElement("div", { className: "brokr-model-dropdown", role: "listbox" }, providers.map((p) => /* @__PURE__ */ import_react32.default.createElement(
|
|
7050
|
+
ModelOption,
|
|
7051
|
+
{
|
|
7052
|
+
key: p.id,
|
|
7053
|
+
provider: p,
|
|
7054
|
+
isActive: p.model === activeModel,
|
|
7055
|
+
isLocked: !availableProviders.some((a) => a.id === p.id),
|
|
7056
|
+
onSelect: handleModelSelect,
|
|
7057
|
+
onCheckout: checkout
|
|
7058
|
+
}
|
|
7059
|
+
))) : null);
|
|
6999
7060
|
}
|
|
7000
7061
|
|
|
7001
7062
|
// src/react/chat/ThreadSidebar.tsx
|
|
7002
7063
|
var import_react33 = __toESM(require("react"));
|
|
7064
|
+
function ThreadItemButton({ id, title, isActive, onSelect }) {
|
|
7065
|
+
const handleClick = (0, import_react33.useCallback)(() => onSelect(id), [id, onSelect]);
|
|
7066
|
+
return /* @__PURE__ */ import_react33.default.createElement(
|
|
7067
|
+
"button",
|
|
7068
|
+
{
|
|
7069
|
+
className: "brokr-ai-chat-conversation",
|
|
7070
|
+
"data-active": isActive,
|
|
7071
|
+
onClick: handleClick,
|
|
7072
|
+
type: "button"
|
|
7073
|
+
},
|
|
7074
|
+
title
|
|
7075
|
+
);
|
|
7076
|
+
}
|
|
7003
7077
|
function ThreadSidebar() {
|
|
7004
7078
|
const {
|
|
7005
7079
|
startNewChat,
|
|
@@ -7050,15 +7124,14 @@ function ThreadSidebar() {
|
|
|
7050
7124
|
value: renameValue
|
|
7051
7125
|
}
|
|
7052
7126
|
) : /* @__PURE__ */ import_react33.default.createElement(
|
|
7053
|
-
|
|
7127
|
+
ThreadItemButton,
|
|
7054
7128
|
{
|
|
7055
|
-
className: "brokr-ai-chat-conversation",
|
|
7056
|
-
"data-active": item.id === activeId,
|
|
7057
7129
|
key: item.id,
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7130
|
+
id: item.id,
|
|
7131
|
+
title: item.title,
|
|
7132
|
+
isActive: item.id === activeId,
|
|
7133
|
+
onSelect: selectThreadAndCloseSidebar
|
|
7134
|
+
}
|
|
7062
7135
|
)));
|
|
7063
7136
|
}, [
|
|
7064
7137
|
threadsLoading,
|
|
@@ -7258,6 +7331,12 @@ function MessageBubble({ message, isTyping, user }) {
|
|
|
7258
7331
|
}
|
|
7259
7332
|
|
|
7260
7333
|
// src/react/chat/MessagePane.tsx
|
|
7334
|
+
function StarterPromptButton({ prompt, onSend }) {
|
|
7335
|
+
const handleClick = (0, import_react36.useCallback)(() => {
|
|
7336
|
+
void onSend(prompt);
|
|
7337
|
+
}, [prompt, onSend]);
|
|
7338
|
+
return /* @__PURE__ */ import_react36.default.createElement("button", { className: "brokr-ai-chat-starter", onClick: handleClick, type: "button" }, prompt);
|
|
7339
|
+
}
|
|
7261
7340
|
function MessagePane({ starterPrompts, emptyTitle, emptyCopy, subtitle }) {
|
|
7262
7341
|
const {
|
|
7263
7342
|
displayMessages,
|
|
@@ -7288,20 +7367,17 @@ function MessagePane({ starterPrompts, emptyTitle, emptyCopy, subtitle }) {
|
|
|
7288
7367
|
);
|
|
7289
7368
|
});
|
|
7290
7369
|
}, [visibleMessages, isSubmitting, user]);
|
|
7291
|
-
return /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread", "data-empty": isEmpty, ref: scrollContainerRef }, isEmpty ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-empty" }, /* @__PURE__ */ import_react36.default.createElement(SparkIcon, { size: 28 }), /* @__PURE__ */ import_react36.default.createElement("h2", { className: "brokr-title" }, emptyTitle), subtitle ?? emptyCopy ? /* @__PURE__ */ import_react36.default.createElement("p", { className: "brokr-copy" }, subtitle ?? emptyCopy) : null, starterPrompts.length > 0 ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-starters" }, starterPrompts.map((sp) => /* @__PURE__ */ import_react36.default.createElement(
|
|
7292
|
-
"button",
|
|
7293
|
-
{
|
|
7294
|
-
className: "brokr-ai-chat-starter",
|
|
7295
|
-
key: sp,
|
|
7296
|
-
onClick: () => void sendMessage(sp),
|
|
7297
|
-
type: "button"
|
|
7298
|
-
},
|
|
7299
|
-
sp
|
|
7300
|
-
))) : null) : /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread-inner" }, (isPersist ? hasMoreMessages : memHasMore) ? /* @__PURE__ */ import_react36.default.createElement("div", { ref: sentinelRef, className: "brokr-ai-chat-sentinel" }, loadingOlder ? /* @__PURE__ */ import_react36.default.createElement("div", { style: { display: "flex", justifyContent: "center", padding: "0.5rem" } }, /* @__PURE__ */ import_react36.default.createElement(Skeleton, { width: 120, height: 12, radius: 6 })) : null) : null, messageElements, /* @__PURE__ */ import_react36.default.createElement("div", { ref: bottomRef })));
|
|
7370
|
+
return /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread", "data-empty": isEmpty, ref: scrollContainerRef }, isEmpty ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-empty" }, /* @__PURE__ */ import_react36.default.createElement(SparkIcon, { size: 28 }), /* @__PURE__ */ import_react36.default.createElement("h2", { className: "brokr-title" }, emptyTitle), subtitle ?? emptyCopy ? /* @__PURE__ */ import_react36.default.createElement("p", { className: "brokr-copy" }, subtitle ?? emptyCopy) : null, starterPrompts.length > 0 ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-starters" }, starterPrompts.map((sp) => /* @__PURE__ */ import_react36.default.createElement(StarterPromptButton, { key: sp, prompt: sp, onSend: sendMessage }))) : null) : /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread-inner" }, (isPersist ? hasMoreMessages : memHasMore) ? /* @__PURE__ */ import_react36.default.createElement("div", { ref: sentinelRef, className: "brokr-ai-chat-sentinel" }, loadingOlder ? /* @__PURE__ */ import_react36.default.createElement("div", { style: { display: "flex", justifyContent: "center", padding: "0.5rem" } }, /* @__PURE__ */ import_react36.default.createElement(Skeleton, { width: 120, height: 12, radius: 6 })) : null) : null, messageElements, /* @__PURE__ */ import_react36.default.createElement("div", { ref: bottomRef })));
|
|
7301
7371
|
}
|
|
7302
7372
|
|
|
7303
7373
|
// src/react/chat/ChatInput.tsx
|
|
7304
7374
|
var import_react37 = __toESM(require("react"));
|
|
7375
|
+
function CommandButton({ cmd, chatContext }) {
|
|
7376
|
+
const handleClick = (0, import_react37.useCallback)(() => {
|
|
7377
|
+
void cmd.run(chatContext);
|
|
7378
|
+
}, [cmd, chatContext]);
|
|
7379
|
+
return /* @__PURE__ */ import_react37.default.createElement("button", { className: "brokr-ai-chat-sidebar-button", key: cmd.id, onClick: handleClick, type: "button" }, cmd.text);
|
|
7380
|
+
}
|
|
7305
7381
|
function ChatInput() {
|
|
7306
7382
|
const {
|
|
7307
7383
|
input,
|
|
@@ -7332,16 +7408,7 @@ function ChatInput() {
|
|
|
7332
7408
|
const handleChange = (0, import_react37.useCallback)((e) => {
|
|
7333
7409
|
setInput(e.target.value);
|
|
7334
7410
|
}, [setInput]);
|
|
7335
|
-
return /* @__PURE__ */ import_react37.default.createElement("form", { className: "brokr-ai-chat-input-area", onSubmit: handleSubmit }, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-container" }, composerCommands.length > 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-composer-actions" }, composerCommands.map((cmd) => /* @__PURE__ */ import_react37.default.createElement(
|
|
7336
|
-
"button",
|
|
7337
|
-
{
|
|
7338
|
-
className: "brokr-ai-chat-sidebar-button",
|
|
7339
|
-
key: cmd.id,
|
|
7340
|
-
onClick: () => void cmd.run(chatContext),
|
|
7341
|
-
type: "button"
|
|
7342
|
-
},
|
|
7343
|
-
cmd.text
|
|
7344
|
-
))) : null, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-row" }, /* @__PURE__ */ import_react37.default.createElement(
|
|
7411
|
+
return /* @__PURE__ */ import_react37.default.createElement("form", { className: "brokr-ai-chat-input-area", onSubmit: handleSubmit }, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-container" }, composerCommands.length > 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-composer-actions" }, composerCommands.map((cmd) => /* @__PURE__ */ import_react37.default.createElement(CommandButton, { key: cmd.id, cmd, chatContext }))) : null, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-row" }, /* @__PURE__ */ import_react37.default.createElement(
|
|
7345
7412
|
"textarea",
|
|
7346
7413
|
{
|
|
7347
7414
|
className: "brokr-ai-chat-textarea",
|
|
@@ -7480,6 +7547,14 @@ function AIChat(inlineProps) {
|
|
|
7480
7547
|
chat.selectThread(id);
|
|
7481
7548
|
setSidebarOpen(false);
|
|
7482
7549
|
}, [chat.selectThread]);
|
|
7550
|
+
const handleCopy = (0, import_react38.useCallback)((content) => {
|
|
7551
|
+
navigator.clipboard.writeText(content).catch(() => {
|
|
7552
|
+
});
|
|
7553
|
+
}, []);
|
|
7554
|
+
const handleStartRename = (0, import_react38.useCallback)((threadId) => {
|
|
7555
|
+
setThreadMenuOpenId(null);
|
|
7556
|
+
chat.startRename(threadId);
|
|
7557
|
+
}, [chat.startRename]);
|
|
7483
7558
|
(0, import_react38.useEffect)(() => {
|
|
7484
7559
|
if (!threadMenuOpenId) return;
|
|
7485
7560
|
const onMouseDown = (e) => {
|
|
@@ -7537,17 +7612,11 @@ function AIChat(inlineProps) {
|
|
|
7537
7612
|
startNewChat: chat.startNewChat,
|
|
7538
7613
|
selectThread: chat.selectThread,
|
|
7539
7614
|
deleteThread: chat.deleteThread,
|
|
7540
|
-
handleCopy
|
|
7541
|
-
navigator.clipboard.writeText(content).catch(() => {
|
|
7542
|
-
});
|
|
7543
|
-
},
|
|
7615
|
+
handleCopy,
|
|
7544
7616
|
renamingId: chat.renamingId,
|
|
7545
7617
|
renameValue: chat.renameValue,
|
|
7546
7618
|
setRenameValue: chat.setRenameValue,
|
|
7547
|
-
startRename:
|
|
7548
|
-
setThreadMenuOpenId(null);
|
|
7549
|
-
chat.startRename(threadId);
|
|
7550
|
-
},
|
|
7619
|
+
startRename: handleStartRename,
|
|
7551
7620
|
submitRename: chat.submitRename,
|
|
7552
7621
|
displaySidebarItems: chat.displaySidebarItems,
|
|
7553
7622
|
threadsLoading: chat.threadsLoading,
|
|
@@ -7633,6 +7702,19 @@ function AIChat(inlineProps) {
|
|
|
7633
7702
|
), /* @__PURE__ */ import_react38.default.createElement(ChatInput, null))
|
|
7634
7703
|
));
|
|
7635
7704
|
}
|
|
7705
|
+
function CommandButton2({ cmd, chatContext }) {
|
|
7706
|
+
const handleClick = (0, import_react38.useCallback)(() => {
|
|
7707
|
+
void cmd.run(chatContext);
|
|
7708
|
+
}, [cmd, chatContext]);
|
|
7709
|
+
return /* @__PURE__ */ import_react38.default.createElement("button", { className: "brokr-ai-chat-sidebar-button", onClick: handleClick, type: "button" }, cmd.text);
|
|
7710
|
+
}
|
|
7711
|
+
function MenuCommandItem({ cmd, chatContext, onClose }) {
|
|
7712
|
+
const handleClick = (0, import_react38.useCallback)(() => {
|
|
7713
|
+
onClose();
|
|
7714
|
+
void cmd.run(chatContext);
|
|
7715
|
+
}, [cmd, chatContext, onClose]);
|
|
7716
|
+
return /* @__PURE__ */ import_react38.default.createElement("button", { className: "brokr-ai-chat-thread-dropdown-item", onClick: handleClick, type: "button" }, cmd.text);
|
|
7717
|
+
}
|
|
7636
7718
|
function ChatHeader({
|
|
7637
7719
|
activeId,
|
|
7638
7720
|
sidebarVisible,
|
|
@@ -7656,6 +7738,16 @@ function ChatHeader({
|
|
|
7656
7738
|
const handleToggleMenu = (0, import_react38.useCallback)(() => {
|
|
7657
7739
|
setThreadMenuOpenId(threadMenuOpenId ? null : activeId);
|
|
7658
7740
|
}, [setThreadMenuOpenId, threadMenuOpenId, activeId]);
|
|
7741
|
+
const closeMenu = (0, import_react38.useCallback)(() => setThreadMenuOpenId(null), [setThreadMenuOpenId]);
|
|
7742
|
+
const handleRename = (0, import_react38.useCallback)(() => {
|
|
7743
|
+
if (activeId) startRename(activeId);
|
|
7744
|
+
}, [activeId, startRename]);
|
|
7745
|
+
const handleDelete = (0, import_react38.useCallback)(() => {
|
|
7746
|
+
if (activeId) {
|
|
7747
|
+
setThreadMenuOpenId(null);
|
|
7748
|
+
void deleteThread(activeId);
|
|
7749
|
+
}
|
|
7750
|
+
}, [activeId, deleteThread, setThreadMenuOpenId]);
|
|
7659
7751
|
return /* @__PURE__ */ import_react38.default.createElement("header", { className: "brokr-ai-chat-topbar" }, /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-left" }, sidebarVisible ? /* @__PURE__ */ import_react38.default.createElement(
|
|
7660
7752
|
"button",
|
|
7661
7753
|
{
|
|
@@ -7665,16 +7757,7 @@ function ChatHeader({
|
|
|
7665
7757
|
type: "button"
|
|
7666
7758
|
},
|
|
7667
7759
|
/* @__PURE__ */ import_react38.default.createElement(MenuIcon, { size: 18 })
|
|
7668
|
-
) : null), /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-actions" }, headerCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(
|
|
7669
|
-
"button",
|
|
7670
|
-
{
|
|
7671
|
-
className: "brokr-ai-chat-sidebar-button",
|
|
7672
|
-
key: cmd.id,
|
|
7673
|
-
onClick: () => void cmd.run(chatContext),
|
|
7674
|
-
type: "button"
|
|
7675
|
-
},
|
|
7676
|
-
cmd.text
|
|
7677
|
-
)), modelSelectorVisible ? /* @__PURE__ */ import_react38.default.createElement(
|
|
7760
|
+
) : null), /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-actions" }, headerCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(CommandButton2, { key: cmd.id, cmd, chatContext })), modelSelectorVisible ? /* @__PURE__ */ import_react38.default.createElement(
|
|
7678
7761
|
ModelSelector,
|
|
7679
7762
|
{
|
|
7680
7763
|
activeModel,
|
|
@@ -7695,32 +7778,25 @@ function ChatHeader({
|
|
|
7695
7778
|
"button",
|
|
7696
7779
|
{
|
|
7697
7780
|
className: "brokr-ai-chat-thread-dropdown-item",
|
|
7698
|
-
onClick:
|
|
7781
|
+
onClick: handleRename,
|
|
7699
7782
|
type: "button"
|
|
7700
7783
|
},
|
|
7701
7784
|
/* @__PURE__ */ import_react38.default.createElement(PencilIcon, { size: 13 }),
|
|
7702
7785
|
"Rename"
|
|
7703
7786
|
), threadMenuCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(
|
|
7704
|
-
|
|
7787
|
+
MenuCommandItem,
|
|
7705
7788
|
{
|
|
7706
|
-
className: "brokr-ai-chat-thread-dropdown-item",
|
|
7707
7789
|
key: cmd.id,
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
type: "button"
|
|
7713
|
-
},
|
|
7714
|
-
cmd.text
|
|
7790
|
+
cmd,
|
|
7791
|
+
chatContext,
|
|
7792
|
+
onClose: closeMenu
|
|
7793
|
+
}
|
|
7715
7794
|
)), /* @__PURE__ */ import_react38.default.createElement(
|
|
7716
7795
|
"button",
|
|
7717
7796
|
{
|
|
7718
7797
|
className: "brokr-ai-chat-thread-dropdown-item",
|
|
7719
7798
|
"data-tone": "danger",
|
|
7720
|
-
onClick:
|
|
7721
|
-
setThreadMenuOpenId(null);
|
|
7722
|
-
void deleteThread(activeId);
|
|
7723
|
-
},
|
|
7799
|
+
onClick: handleDelete,
|
|
7724
7800
|
type: "button"
|
|
7725
7801
|
},
|
|
7726
7802
|
/* @__PURE__ */ import_react38.default.createElement(TrashIcon, { size: 13 }),
|
|
@@ -7730,6 +7806,10 @@ function ChatHeader({
|
|
|
7730
7806
|
|
|
7731
7807
|
// src/react/composites/FabAI.tsx
|
|
7732
7808
|
var import_react39 = __toESM(require("react"));
|
|
7809
|
+
function StarterButton({ prompt, onSelect }) {
|
|
7810
|
+
const handleClick = (0, import_react39.useCallback)(() => onSelect(prompt), [prompt, onSelect]);
|
|
7811
|
+
return /* @__PURE__ */ import_react39.default.createElement("button", { className: "brokr-chat-starter", onClick: handleClick, type: "button" }, prompt);
|
|
7812
|
+
}
|
|
7733
7813
|
function FabAI({
|
|
7734
7814
|
model,
|
|
7735
7815
|
onSendMessage,
|
|
@@ -7821,30 +7901,16 @@ function FabAI({
|
|
|
7821
7901
|
},
|
|
7822
7902
|
/* @__PURE__ */ import_react39.default.createElement(MessageIcon, { size: 16 }),
|
|
7823
7903
|
"Ask AI"
|
|
7824
|
-
)), isOpen ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-panel brokr-chat-panel", role: "dialog" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "
|
|
7904
|
+
)), isOpen ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-panel brokr-chat-panel", role: "dialog" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "AI Chat"), user?.name ? /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, user.name) : null), /* @__PURE__ */ import_react39.default.createElement("button", { className: "brokr-button-ghost", onClick: handleClose, type: "button" }, /* @__PURE__ */ import_react39.default.createElement(CloseIcon, { size: 16 }))), /* @__PURE__ */ import_react39.default.createElement(
|
|
7825
7905
|
"div",
|
|
7826
7906
|
{
|
|
7827
7907
|
className: "brokr-chat-messages",
|
|
7828
7908
|
"data-empty": messages.length === 0
|
|
7829
7909
|
},
|
|
7830
|
-
messages.length === 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-empty" }, /* @__PURE__ */ import_react39.default.createElement(SparkIcon, { size: 18 }), /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "
|
|
7831
|
-
const handleClick = () => {
|
|
7832
|
-
handleStarterPrompt(prompt);
|
|
7833
|
-
};
|
|
7834
|
-
return /* @__PURE__ */ import_react39.default.createElement(
|
|
7835
|
-
"button",
|
|
7836
|
-
{
|
|
7837
|
-
className: "brokr-chat-starter",
|
|
7838
|
-
key: prompt,
|
|
7839
|
-
onClick: handleClick,
|
|
7840
|
-
type: "button"
|
|
7841
|
-
},
|
|
7842
|
-
prompt
|
|
7843
|
-
);
|
|
7844
|
-
})) : null) : null,
|
|
7910
|
+
messages.length === 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-empty" }, /* @__PURE__ */ import_react39.default.createElement(SparkIcon, { size: 18 }), /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "Send a message to chat with the AI."), /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, "Ask a question or drop in a starter prompt below.")), starterPrompts.length > 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-starters" }, starterPrompts.map((prompt) => /* @__PURE__ */ import_react39.default.createElement(StarterButton, { key: prompt, prompt, onSelect: handleStarterPrompt }))) : null) : null,
|
|
7845
7911
|
messages.map((message, index) => /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-bubble", "data-role": message.role, key: `${message.role}-${index}` }, contentToText(message.content))),
|
|
7846
7912
|
error ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null
|
|
7847
|
-
), /* @__PURE__ */ import_react39.default.createElement("form", { className: "brokr-section", onSubmit: handleSubmit, style: { gap: "
|
|
7913
|
+
), /* @__PURE__ */ import_react39.default.createElement("form", { className: "brokr-section", onSubmit: handleSubmit, style: { gap: "var(--brokr-space-3)" } }, /* @__PURE__ */ import_react39.default.createElement(
|
|
7848
7914
|
"textarea",
|
|
7849
7915
|
{
|
|
7850
7916
|
className: "brokr-textarea brokr-chat-input",
|
|
@@ -7937,7 +8003,7 @@ function SmartUpload({
|
|
|
7937
8003
|
const handleBrowse = (0, import_react40.useCallback)(() => {
|
|
7938
8004
|
inputRef.current?.click();
|
|
7939
8005
|
}, []);
|
|
7940
|
-
return /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-shell" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "
|
|
8006
|
+
return /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-shell" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, "Upload files"), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, "Drop a file and let Brokr handle the boring part.")), paymentsMode === "sandbox" ? /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-badge brokr-badge-sandbox" }, "Sandbox") : null), /* @__PURE__ */ import_react40.default.createElement(
|
|
7941
8007
|
"label",
|
|
7942
8008
|
{
|
|
7943
8009
|
className: "brokr-upload-dropzone",
|
|
@@ -7962,7 +8028,7 @@ function SmartUpload({
|
|
|
7962
8028
|
ref: inputRef,
|
|
7963
8029
|
type: "file"
|
|
7964
8030
|
}
|
|
7965
|
-
), fileName ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-file" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "
|
|
8031
|
+
), fileName ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-file" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, fileName), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, isUploading ? `Uploading ${progress}%` : progress === 100 ? "Processed" : "Queued")), /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-bar" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-fill", style: { width: `${progress}%` } }))) : null, error ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null);
|
|
7966
8032
|
}
|
|
7967
8033
|
|
|
7968
8034
|
// src/react/composites/FeedbackWidget.tsx
|
|
@@ -8327,6 +8393,28 @@ function timeAgo(iso) {
|
|
|
8327
8393
|
const days = Math.floor(hours / 24);
|
|
8328
8394
|
return `${days}d ago`;
|
|
8329
8395
|
}
|
|
8396
|
+
function NotifDropdownItem({
|
|
8397
|
+
notif,
|
|
8398
|
+
registry,
|
|
8399
|
+
onClick
|
|
8400
|
+
}) {
|
|
8401
|
+
const handleClick = (0, import_react44.useCallback)(() => onClick(notif), [notif, onClick]);
|
|
8402
|
+
const notifData = notif.data ?? {};
|
|
8403
|
+
const notifType = notifData.type ?? "default";
|
|
8404
|
+
const resolved = resolveNotificationType(registry, notifType, notifData);
|
|
8405
|
+
return /* @__PURE__ */ import_react44.default.createElement(
|
|
8406
|
+
"button",
|
|
8407
|
+
{
|
|
8408
|
+
type: "button",
|
|
8409
|
+
className: `brokr-notif-item${notif.read ? "" : " brokr-notif-item--unread"}`,
|
|
8410
|
+
onClick: handleClick,
|
|
8411
|
+
role: "menuitem"
|
|
8412
|
+
},
|
|
8413
|
+
resolved.image ? /* @__PURE__ */ import_react44.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-notif-item-logo" }) : /* @__PURE__ */ import_react44.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
|
|
8414
|
+
/* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
|
|
8415
|
+
/* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-time" }, timeAgo(notif.createdAt))
|
|
8416
|
+
);
|
|
8417
|
+
}
|
|
8330
8418
|
function NotificationBell() {
|
|
8331
8419
|
const { notifications, unreadCount, markRead, markAllRead, isLoading, registry } = useNotifications();
|
|
8332
8420
|
const [open, setOpen] = (0, import_react44.useState)(false);
|
|
@@ -8391,7 +8479,8 @@ function NotificationBell() {
|
|
|
8391
8479
|
className: "brokr-notif-bell",
|
|
8392
8480
|
onClick: toggle,
|
|
8393
8481
|
"aria-label": `Notifications${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
|
|
8394
|
-
"aria-expanded": open
|
|
8482
|
+
"aria-expanded": open,
|
|
8483
|
+
"aria-haspopup": "menu"
|
|
8395
8484
|
},
|
|
8396
8485
|
/* @__PURE__ */ import_react44.default.createElement("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react44.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react44.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })),
|
|
8397
8486
|
unreadCount > 0 && /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-badge" }, unreadCount > 99 ? "99+" : unreadCount)
|
|
@@ -8403,31 +8492,15 @@ function NotificationBell() {
|
|
|
8403
8492
|
onClick: markAllRead
|
|
8404
8493
|
},
|
|
8405
8494
|
"Mark all read"
|
|
8406
|
-
)), /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-dropdown-list" }, isLoading ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "Loading\u2026")) : sorted.length === 0 ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : sorted.map((notif) =>
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
className: `brokr-notif-item${notif.read ? "" : " brokr-notif-item--unread"}`,
|
|
8416
|
-
onClick: () => handleItemClick(notif),
|
|
8417
|
-
role: "menuitem"
|
|
8418
|
-
},
|
|
8419
|
-
resolved.image ? /* @__PURE__ */ import_react44.default.createElement(
|
|
8420
|
-
"img",
|
|
8421
|
-
{
|
|
8422
|
-
src: resolved.image.url,
|
|
8423
|
-
alt: resolved.image.alt,
|
|
8424
|
-
className: "brokr-notif-item-logo"
|
|
8425
|
-
}
|
|
8426
|
-
) : /* @__PURE__ */ import_react44.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
|
|
8427
|
-
/* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
|
|
8428
|
-
/* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-time" }, timeAgo(notif.createdAt))
|
|
8429
|
-
);
|
|
8430
|
-
}))));
|
|
8495
|
+
)), /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-dropdown-list" }, isLoading ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "Loading\u2026")) : sorted.length === 0 ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : sorted.map((notif) => /* @__PURE__ */ import_react44.default.createElement(
|
|
8496
|
+
NotifDropdownItem,
|
|
8497
|
+
{
|
|
8498
|
+
key: notif.id,
|
|
8499
|
+
notif,
|
|
8500
|
+
registry,
|
|
8501
|
+
onClick: handleItemClick
|
|
8502
|
+
}
|
|
8503
|
+
)))));
|
|
8431
8504
|
}
|
|
8432
8505
|
|
|
8433
8506
|
// src/react/notifications/NotificationList.tsx
|
|
@@ -8444,6 +8517,27 @@ function formatTimestamp(iso) {
|
|
|
8444
8517
|
function NotificationListSkeleton() {
|
|
8445
8518
|
return /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, [1, 2, 3].map((i) => /* @__PURE__ */ import_react45.default.createElement("div", { key: i, className: "brokr-notif-list-row brokr-notif-list-row--skeleton" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-dot brokr-notif-item-dot--skeleton" }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title brokr-skeleton-line", style: { width: "60%" } }), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message brokr-skeleton-line", style: { width: "80%" } })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time brokr-skeleton-line", style: { width: 48 } }))));
|
|
8446
8519
|
}
|
|
8520
|
+
function NotifListItem({
|
|
8521
|
+
notif,
|
|
8522
|
+
registry,
|
|
8523
|
+
onClick
|
|
8524
|
+
}) {
|
|
8525
|
+
const handleClick = (0, import_react45.useCallback)(() => onClick(notif), [notif, onClick]);
|
|
8526
|
+
const notifData = notif.data ?? {};
|
|
8527
|
+
const notifType = notif.type ?? notifData.type ?? "default";
|
|
8528
|
+
const resolved = resolveNotificationType(registry, notifType, notifData);
|
|
8529
|
+
return /* @__PURE__ */ import_react45.default.createElement(
|
|
8530
|
+
"button",
|
|
8531
|
+
{
|
|
8532
|
+
type: "button",
|
|
8533
|
+
className: `brokr-notif-list-row${notif.read ? "" : " brokr-notif-list-row--unread"}`,
|
|
8534
|
+
onClick: handleClick
|
|
8535
|
+
},
|
|
8536
|
+
resolved.image ? /* @__PURE__ */ import_react45.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-notif-item-logo" }) : /* @__PURE__ */ import_react45.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
|
|
8537
|
+
/* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
|
|
8538
|
+
/* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time" }, formatTimestamp(notif.createdAt))
|
|
8539
|
+
);
|
|
8540
|
+
}
|
|
8447
8541
|
function NotificationList() {
|
|
8448
8542
|
const { notifications, unreadCount, markRead, markAllRead, isLoading, registry } = useNotifications();
|
|
8449
8543
|
const sorted = (0, import_react45.useMemo)(
|
|
@@ -8470,30 +8564,15 @@ function NotificationList() {
|
|
|
8470
8564
|
onClick: markAllRead
|
|
8471
8565
|
},
|
|
8472
8566
|
"Mark all read"
|
|
8473
|
-
)), isLoading ? /* @__PURE__ */ import_react45.default.createElement(NotificationListSkeleton, null) : sorted.length === 0 ? /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react45.default.createElement("svg", { "aria-hidden": "true", width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round", strokeLinejoin: "round", style: { opacity: 0.3 } }, /* @__PURE__ */ import_react45.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react45.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, sorted.map((notif) =>
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
className: `brokr-notif-list-row${notif.read ? "" : " brokr-notif-list-row--unread"}`,
|
|
8483
|
-
onClick: () => handleClick(notif)
|
|
8484
|
-
},
|
|
8485
|
-
resolved.image ? /* @__PURE__ */ import_react45.default.createElement(
|
|
8486
|
-
"img",
|
|
8487
|
-
{
|
|
8488
|
-
src: resolved.image.url,
|
|
8489
|
-
alt: resolved.image.alt,
|
|
8490
|
-
className: "brokr-notif-item-logo"
|
|
8491
|
-
}
|
|
8492
|
-
) : /* @__PURE__ */ import_react45.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
|
|
8493
|
-
/* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
|
|
8494
|
-
/* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time" }, formatTimestamp(notif.createdAt))
|
|
8495
|
-
);
|
|
8496
|
-
})));
|
|
8567
|
+
)), isLoading ? /* @__PURE__ */ import_react45.default.createElement(NotificationListSkeleton, null) : sorted.length === 0 ? /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react45.default.createElement("svg", { "aria-hidden": "true", width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round", strokeLinejoin: "round", style: { opacity: 0.3 } }, /* @__PURE__ */ import_react45.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react45.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, sorted.map((notif) => /* @__PURE__ */ import_react45.default.createElement(
|
|
8568
|
+
NotifListItem,
|
|
8569
|
+
{
|
|
8570
|
+
key: notif.id,
|
|
8571
|
+
notif,
|
|
8572
|
+
registry,
|
|
8573
|
+
onClick: handleClick
|
|
8574
|
+
}
|
|
8575
|
+
))));
|
|
8497
8576
|
}
|
|
8498
8577
|
|
|
8499
8578
|
// src/react/hooks/use-user.ts
|