@natoe/colab 0.1.12 → 0.1.13
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/index.d.mts +132 -13
- package/dist/index.d.ts +132 -13
- package/dist/index.js +1056 -608
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1055 -610
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React4, { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useCallback, useState,
|
|
1
|
+
import React4, { createContext, forwardRef, useRef, useImperativeHandle, useLayoutEffect, useEffect, useCallback, useState, useContext, useId, useMemo } from 'react';
|
|
2
2
|
import { Socket, Presence } from 'phoenix';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
@@ -315,6 +315,173 @@ var CollabSocket = class {
|
|
|
315
315
|
this.config = null;
|
|
316
316
|
}
|
|
317
317
|
};
|
|
318
|
+
|
|
319
|
+
// src/core/theme.ts
|
|
320
|
+
var FONT_SIZE = {
|
|
321
|
+
xs: "12px",
|
|
322
|
+
sm: "13px",
|
|
323
|
+
md: "15px",
|
|
324
|
+
lg: "17px",
|
|
325
|
+
xxl: "28px"
|
|
326
|
+
};
|
|
327
|
+
var FONT_WEIGHT = {
|
|
328
|
+
regular: 400,
|
|
329
|
+
medium: 500,
|
|
330
|
+
semibold: 600,
|
|
331
|
+
bold: 700
|
|
332
|
+
};
|
|
333
|
+
var LINE_HEIGHT = {
|
|
334
|
+
tight: 1.3,
|
|
335
|
+
normal: 1.45};
|
|
336
|
+
var SPACE = {
|
|
337
|
+
S1: "4px",
|
|
338
|
+
S2: "8px",
|
|
339
|
+
S3: "12px",
|
|
340
|
+
S4: "16px",
|
|
341
|
+
S5: "20px",
|
|
342
|
+
S6: "24px",
|
|
343
|
+
S12: "48px"
|
|
344
|
+
};
|
|
345
|
+
var RADIUS = {
|
|
346
|
+
sm: "4px",
|
|
347
|
+
md: "8px",
|
|
348
|
+
lg: "12px",
|
|
349
|
+
xl: "16px",
|
|
350
|
+
pill: "9999px",
|
|
351
|
+
full: "50%"
|
|
352
|
+
};
|
|
353
|
+
var THEME_VAR = {
|
|
354
|
+
primary: "--natoe-colab-primary",
|
|
355
|
+
primaryHover: "--natoe-colab-primary-hover",
|
|
356
|
+
primaryBg: "--natoe-colab-primary-bg",
|
|
357
|
+
primaryFg: "--natoe-colab-primary-fg",
|
|
358
|
+
success: "--natoe-colab-success",
|
|
359
|
+
warning: "--natoe-colab-warning",
|
|
360
|
+
danger: "--natoe-colab-danger",
|
|
361
|
+
dangerBg: "--natoe-colab-danger-bg",
|
|
362
|
+
dangerBorder: "--natoe-colab-danger-border",
|
|
363
|
+
dangerFg: "--natoe-colab-danger-fg",
|
|
364
|
+
fontStack: "--natoe-colab-font-stack"
|
|
365
|
+
};
|
|
366
|
+
var THEME_DEFAULTS = {
|
|
367
|
+
primary: "#2563eb",
|
|
368
|
+
primaryHover: "#1d4ed8",
|
|
369
|
+
primaryBg: "#dbeafe",
|
|
370
|
+
primaryFg: "#1d4ed8",
|
|
371
|
+
success: "#059669",
|
|
372
|
+
warning: "#d97706",
|
|
373
|
+
danger: "#dc2626",
|
|
374
|
+
dangerBg: "#fef2f2",
|
|
375
|
+
dangerBorder: "#fecaca",
|
|
376
|
+
dangerFg: "#b91c1c",
|
|
377
|
+
fontStack: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
|
|
378
|
+
};
|
|
379
|
+
var cssVar = (name, fallback) => `var(${name}, ${fallback})`;
|
|
380
|
+
var COLOR = {
|
|
381
|
+
// Brand — themeable
|
|
382
|
+
primary: cssVar(THEME_VAR.primary, THEME_DEFAULTS.primary),
|
|
383
|
+
primaryHover: cssVar(THEME_VAR.primaryHover, THEME_DEFAULTS.primaryHover),
|
|
384
|
+
/** Tinted surface for chips/cards on brand-coloured states. */
|
|
385
|
+
primaryBg: cssVar(THEME_VAR.primaryBg, THEME_DEFAULTS.primaryBg),
|
|
386
|
+
primaryFg: cssVar(THEME_VAR.primaryFg, THEME_DEFAULTS.primaryFg),
|
|
387
|
+
// Neutral grayscale — not themeable, taken from Tailwind's zinc-leaning
|
|
388
|
+
// slate to match the package's existing tonal balance.
|
|
389
|
+
white: "#ffffff",
|
|
390
|
+
neutral50: "#f9fafb",
|
|
391
|
+
neutral100: "#f3f4f6",
|
|
392
|
+
neutral200: "#e5e7eb",
|
|
393
|
+
neutral300: "#d1d5db",
|
|
394
|
+
neutral400: "#9ca3af",
|
|
395
|
+
neutral500: "#6b7280",
|
|
396
|
+
neutral600: "#4b5563",
|
|
397
|
+
neutral700: "#374151",
|
|
398
|
+
neutral800: "#1f2937",
|
|
399
|
+
neutral900: "#111827",
|
|
400
|
+
slate800: "#1e293b",
|
|
401
|
+
// Semantic — themeable
|
|
402
|
+
success: cssVar(THEME_VAR.success, THEME_DEFAULTS.success),
|
|
403
|
+
warning: cssVar(THEME_VAR.warning, THEME_DEFAULTS.warning),
|
|
404
|
+
danger: cssVar(THEME_VAR.danger, THEME_DEFAULTS.danger),
|
|
405
|
+
dangerBg: cssVar(THEME_VAR.dangerBg, THEME_DEFAULTS.dangerBg),
|
|
406
|
+
dangerBorder: cssVar(THEME_VAR.dangerBorder, THEME_DEFAULTS.dangerBorder),
|
|
407
|
+
dangerFg: cssVar(THEME_VAR.dangerFg, THEME_DEFAULTS.dangerFg)
|
|
408
|
+
};
|
|
409
|
+
var SIZE = {
|
|
410
|
+
/** Default interactive height (text buttons, list rows). */
|
|
411
|
+
control: "40px",
|
|
412
|
+
/** Square icon-only buttons inside chrome (popup title, menu trigger). */
|
|
413
|
+
controlIcon: "36px"};
|
|
414
|
+
var SHADOW = {
|
|
415
|
+
/** Cards / floating popovers (message-actions menu). */
|
|
416
|
+
popover: "0 6px 18px rgba(0, 0, 0, 0.12)",
|
|
417
|
+
toast: "0 4px 12px rgba(0, 0, 0, 0.18)"
|
|
418
|
+
};
|
|
419
|
+
var Z_INDEX = {
|
|
420
|
+
/** Sticky day divider — above bubbles, below interactive popovers. */
|
|
421
|
+
sticky: 1,
|
|
422
|
+
/** Toasts inside a panel. */
|
|
423
|
+
toast: 20,
|
|
424
|
+
/** Floating CollabPopup dialog. */
|
|
425
|
+
dialog: 9999,
|
|
426
|
+
/** Portaled message-actions menu — must sit above the dialog. */
|
|
427
|
+
menu: 1e4
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
// src/core/styles.ts
|
|
431
|
+
var FONT_STACK = `var(${THEME_VAR.fontStack}, ${THEME_DEFAULTS.fontStack})`;
|
|
432
|
+
var ROOT_CLASS = "natoe-colab-root";
|
|
433
|
+
var GLOBAL_STYLE_ID = "natoe-colab-global-styles";
|
|
434
|
+
var ROOT_DEFAULTS_BLOCK = Object.keys(THEME_DEFAULTS).map((key) => ` ${THEME_VAR[key]}: ${THEME_DEFAULTS[key]};`).join("\n");
|
|
435
|
+
var GLOBAL_CSS = `
|
|
436
|
+
:root {
|
|
437
|
+
${ROOT_DEFAULTS_BLOCK}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }
|
|
441
|
+
|
|
442
|
+
@keyframes natoe-colab-message-in {
|
|
443
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
444
|
+
to { opacity: 1; transform: translateY(0); }
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/* High-contrast adjustments \u2014 older users on OS-level high-contrast mode
|
|
448
|
+
get heavier borders and stronger text without losing the package look. */
|
|
449
|
+
@media (prefers-contrast: more) {
|
|
450
|
+
.${ROOT_CLASS} {
|
|
451
|
+
color: #000000;
|
|
452
|
+
}
|
|
453
|
+
.${ROOT_CLASS} button {
|
|
454
|
+
outline: 1px solid currentColor;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* Honour reduced-motion preferences by killing entry animations. */
|
|
459
|
+
@media (prefers-reduced-motion: reduce) {
|
|
460
|
+
.${ROOT_CLASS} [data-natoe-message-bubble] {
|
|
461
|
+
animation: none !important;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
`;
|
|
465
|
+
function ensureGlobalStyles() {
|
|
466
|
+
if (typeof document === "undefined") return;
|
|
467
|
+
if (document.getElementById(GLOBAL_STYLE_ID)) return;
|
|
468
|
+
const style = document.createElement("style");
|
|
469
|
+
style.id = GLOBAL_STYLE_ID;
|
|
470
|
+
style.textContent = GLOBAL_CSS;
|
|
471
|
+
document.head.appendChild(style);
|
|
472
|
+
}
|
|
473
|
+
function applyThemeOverrides(theme) {
|
|
474
|
+
if (typeof document === "undefined") return;
|
|
475
|
+
const root = document.documentElement;
|
|
476
|
+
Object.keys(THEME_VAR).forEach((key) => {
|
|
477
|
+
const value = theme?.[key];
|
|
478
|
+
if (value) {
|
|
479
|
+
root.style.setProperty(THEME_VAR[key], value);
|
|
480
|
+
} else {
|
|
481
|
+
root.style.removeProperty(THEME_VAR[key]);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}
|
|
318
485
|
var CollabContext = createContext(null);
|
|
319
486
|
function useCollab() {
|
|
320
487
|
const context = useContext(CollabContext);
|
|
@@ -333,6 +500,9 @@ function CollabProvider({ config, apiBaseUrl, children }) {
|
|
|
333
500
|
const pendingResolvers = useRef(/* @__PURE__ */ new Map());
|
|
334
501
|
const previewCache = useRef(/* @__PURE__ */ new Map());
|
|
335
502
|
const batchScheduled = useRef(false);
|
|
503
|
+
useEffect(() => {
|
|
504
|
+
applyThemeOverrides(config.theme);
|
|
505
|
+
}, [config.theme]);
|
|
336
506
|
useEffect(() => {
|
|
337
507
|
if (typeof window === "undefined") return;
|
|
338
508
|
let s = socket;
|
|
@@ -548,6 +718,7 @@ function CollabProvider({ config, apiBaseUrl, children }) {
|
|
|
548
718
|
config,
|
|
549
719
|
apiBaseUrl,
|
|
550
720
|
totalUnread,
|
|
721
|
+
unreadCounts,
|
|
551
722
|
requestPreview,
|
|
552
723
|
invalidatePreview,
|
|
553
724
|
fetchMessages,
|
|
@@ -725,26 +896,22 @@ function useConversation({
|
|
|
725
896
|
setConversation(existingConv);
|
|
726
897
|
setParticipants(preview.participants);
|
|
727
898
|
joinChannel(existingConv);
|
|
728
|
-
setMessages(preview.lastMessages);
|
|
729
|
-
setHasMore(preview.messageCount > preview.lastMessages.length);
|
|
730
|
-
setPinnedMessages(preview.lastMessages.filter((m) => m.isPinned));
|
|
731
|
-
setIsLoading(false);
|
|
732
899
|
if (loadHistory) {
|
|
733
900
|
fetchMessages(preview.conversationId).then((history) => {
|
|
734
901
|
if (cancelled) return;
|
|
735
|
-
setMessages(
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
});
|
|
740
|
-
setHasMore(history.length > 0);
|
|
741
|
-
setPinnedMessages((prev) => {
|
|
742
|
-
const fromHistory = history.filter((m) => m.isPinned);
|
|
743
|
-
const seen = new Set(prev.map((m) => m.id));
|
|
744
|
-
return [...fromHistory.filter((m) => !seen.has(m.id)), ...prev];
|
|
745
|
-
});
|
|
902
|
+
setMessages(history);
|
|
903
|
+
setHasMore(history.length >= MESSAGES_PAGE_SIZE);
|
|
904
|
+
setPinnedMessages(history.filter((m) => m.isPinned));
|
|
905
|
+
setIsLoading(false);
|
|
746
906
|
}).catch(() => {
|
|
907
|
+
if (cancelled) return;
|
|
908
|
+
setIsLoading(false);
|
|
747
909
|
});
|
|
910
|
+
} else {
|
|
911
|
+
setMessages([]);
|
|
912
|
+
setHasMore(false);
|
|
913
|
+
setPinnedMessages([]);
|
|
914
|
+
setIsLoading(false);
|
|
748
915
|
}
|
|
749
916
|
} catch (err) {
|
|
750
917
|
if (cancelled) return;
|
|
@@ -825,7 +992,7 @@ function useConversation({
|
|
|
825
992
|
const payload = {
|
|
826
993
|
body,
|
|
827
994
|
type: "text",
|
|
828
|
-
...replyTo ? {
|
|
995
|
+
...replyTo ? { reply_to_id: replyTo.id } : {}
|
|
829
996
|
};
|
|
830
997
|
const { conv, persistedByCreate } = await ensureConversation(payload);
|
|
831
998
|
setReplyTo(null);
|
|
@@ -878,7 +1045,7 @@ function useConversation({
|
|
|
878
1045
|
const payload = {
|
|
879
1046
|
body: target.body,
|
|
880
1047
|
type: "text",
|
|
881
|
-
...target.replyToId ? {
|
|
1048
|
+
...target.replyToId ? { reply_to_id: target.replyToId } : {}
|
|
882
1049
|
};
|
|
883
1050
|
try {
|
|
884
1051
|
await socket.sendMessage(conversation.id, payload);
|
|
@@ -1203,102 +1370,6 @@ function BackIcon({ size = 22, color = "currentColor" }) {
|
|
|
1203
1370
|
}
|
|
1204
1371
|
);
|
|
1205
1372
|
}
|
|
1206
|
-
|
|
1207
|
-
// src/core/theme.ts
|
|
1208
|
-
var FONT_SIZE = {
|
|
1209
|
-
xs: "12px",
|
|
1210
|
-
sm: "13px",
|
|
1211
|
-
md: "15px",
|
|
1212
|
-
lg: "17px",
|
|
1213
|
-
xxl: "28px"
|
|
1214
|
-
};
|
|
1215
|
-
var FONT_WEIGHT = {
|
|
1216
|
-
regular: 400,
|
|
1217
|
-
medium: 500,
|
|
1218
|
-
semibold: 600,
|
|
1219
|
-
bold: 700
|
|
1220
|
-
};
|
|
1221
|
-
var LINE_HEIGHT = {
|
|
1222
|
-
tight: 1.3,
|
|
1223
|
-
normal: 1.45};
|
|
1224
|
-
var SPACE = {
|
|
1225
|
-
S1: "4px",
|
|
1226
|
-
S2: "8px",
|
|
1227
|
-
S3: "12px",
|
|
1228
|
-
S4: "16px",
|
|
1229
|
-
S5: "20px",
|
|
1230
|
-
S6: "24px",
|
|
1231
|
-
S12: "48px"
|
|
1232
|
-
};
|
|
1233
|
-
var RADIUS = {
|
|
1234
|
-
sm: "4px",
|
|
1235
|
-
md: "8px",
|
|
1236
|
-
lg: "12px",
|
|
1237
|
-
pill: "9999px",
|
|
1238
|
-
full: "50%"
|
|
1239
|
-
};
|
|
1240
|
-
var COLOR = {
|
|
1241
|
-
// Brand
|
|
1242
|
-
primary: "#2563eb",
|
|
1243
|
-
/** Tinted surface for chips/cards on brand-coloured states. */
|
|
1244
|
-
primaryBg: "#dbeafe",
|
|
1245
|
-
primaryFg: "#1d4ed8",
|
|
1246
|
-
// Neutral grayscale — taken from Tailwind's zinc-leaning slate, the
|
|
1247
|
-
// existing dominant family in the package.
|
|
1248
|
-
white: "#ffffff",
|
|
1249
|
-
neutral50: "#f9fafb",
|
|
1250
|
-
neutral100: "#f3f4f6",
|
|
1251
|
-
neutral200: "#e5e7eb",
|
|
1252
|
-
neutral300: "#d1d5db",
|
|
1253
|
-
neutral400: "#9ca3af",
|
|
1254
|
-
neutral500: "#6b7280",
|
|
1255
|
-
neutral600: "#4b5563",
|
|
1256
|
-
neutral700: "#374151",
|
|
1257
|
-
neutral800: "#1f2937",
|
|
1258
|
-
neutral900: "#111827",
|
|
1259
|
-
// Slate (used by day dividers + dialog title bar)
|
|
1260
|
-
slate200: "#e2e8f0",
|
|
1261
|
-
slate700: "#334155",
|
|
1262
|
-
slate800: "#1e293b",
|
|
1263
|
-
// Semantic
|
|
1264
|
-
success: "#059669",
|
|
1265
|
-
warning: "#d97706",
|
|
1266
|
-
danger: "#dc2626",
|
|
1267
|
-
dangerBg: "#fef2f2",
|
|
1268
|
-
dangerBorder: "#fecaca",
|
|
1269
|
-
dangerFg: "#b91c1c"
|
|
1270
|
-
};
|
|
1271
|
-
var SIZE = {
|
|
1272
|
-
/** Default interactive height (text buttons, list rows). */
|
|
1273
|
-
control: "40px",
|
|
1274
|
-
/** Square icon-only buttons inside chrome (popup title, menu trigger). */
|
|
1275
|
-
controlIcon: "36px",
|
|
1276
|
-
/** Primary input controls (textarea send/attach). 44px = WCAG min. */
|
|
1277
|
-
controlPrimary: "44px",
|
|
1278
|
-
/** Avatar in the inbox row. */
|
|
1279
|
-
avatar: "40px",
|
|
1280
|
-
/** Unread dot. */
|
|
1281
|
-
dot: "10px"
|
|
1282
|
-
};
|
|
1283
|
-
var SHADOW = {
|
|
1284
|
-
/** Cards / floating popovers (message-actions menu). */
|
|
1285
|
-
popover: "0 6px 18px rgba(0, 0, 0, 0.12)",
|
|
1286
|
-
/** Dialog (CollabPopup). */
|
|
1287
|
-
dialog: "0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)",
|
|
1288
|
-
/** Subtle separator shadow (sticky day divider, toast). */
|
|
1289
|
-
subtle: "0 1px 2px rgba(0, 0, 0, 0.04)",
|
|
1290
|
-
toast: "0 4px 12px rgba(0, 0, 0, 0.18)"
|
|
1291
|
-
};
|
|
1292
|
-
var Z_INDEX = {
|
|
1293
|
-
/** Sticky day divider — above bubbles, below interactive popovers. */
|
|
1294
|
-
sticky: 1,
|
|
1295
|
-
/** Toasts inside a panel. */
|
|
1296
|
-
toast: 20,
|
|
1297
|
-
/** Floating CollabPopup dialog. */
|
|
1298
|
-
dialog: 9999,
|
|
1299
|
-
/** Portaled message-actions menu — must sit above the dialog. */
|
|
1300
|
-
menu: 1e4
|
|
1301
|
-
};
|
|
1302
1373
|
function resolveDisplayName(patientData, displayName) {
|
|
1303
1374
|
const localComplete = !!patientData.labName && !!patientData.displayOrderId;
|
|
1304
1375
|
if (localComplete) return buildChannelName(patientData);
|
|
@@ -1315,15 +1386,28 @@ function PatientHeader({
|
|
|
1315
1386
|
}) {
|
|
1316
1387
|
const hasDicom = !!(patientData.studyId && patientData.storageId);
|
|
1317
1388
|
const meta = [];
|
|
1318
|
-
if (patientData.patientAge
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1389
|
+
if (patientData.patientAge && patientData.patientSex) {
|
|
1390
|
+
meta.push({
|
|
1391
|
+
key: "ageSex",
|
|
1392
|
+
label: "Age / Sex",
|
|
1393
|
+
value: `${patientData.patientAge} \xB7 ${patientData.patientSex}`
|
|
1394
|
+
});
|
|
1395
|
+
} else if (patientData.patientAge) {
|
|
1396
|
+
meta.push({ key: "age", label: "Age", value: String(patientData.patientAge) });
|
|
1397
|
+
} else if (patientData.patientSex) {
|
|
1398
|
+
meta.push({ key: "sex", label: "Sex", value: String(patientData.patientSex) });
|
|
1399
|
+
}
|
|
1400
|
+
if (patientData.studyType) {
|
|
1401
|
+
meta.push({ key: "modality", label: "Modality", value: patientData.studyType });
|
|
1323
1402
|
}
|
|
1324
|
-
if (patientData.
|
|
1325
|
-
meta.push({
|
|
1403
|
+
if (patientData.bodyParts && patientData.bodyParts.length > 0) {
|
|
1404
|
+
meta.push({
|
|
1405
|
+
key: "body",
|
|
1406
|
+
label: "Body part",
|
|
1407
|
+
value: patientData.bodyParts.join(", ")
|
|
1408
|
+
});
|
|
1326
1409
|
}
|
|
1410
|
+
const hasActions = hasDicom && onOpenDicom || onOpenSettings;
|
|
1327
1411
|
return /* @__PURE__ */ jsxs("div", { className, style: styles.container, children: [
|
|
1328
1412
|
!hideName && /* @__PURE__ */ jsxs("div", { style: styles.nameRow, children: [
|
|
1329
1413
|
onBack && /* @__PURE__ */ jsx(
|
|
@@ -1339,54 +1423,55 @@ function PatientHeader({
|
|
|
1339
1423
|
),
|
|
1340
1424
|
/* @__PURE__ */ jsx("span", { style: styles.nameText, children: resolveDisplayName(patientData, displayName) })
|
|
1341
1425
|
] }),
|
|
1342
|
-
|
|
1343
|
-
/* @__PURE__ */ jsxs("
|
|
1344
|
-
item.label,
|
|
1345
|
-
":
|
|
1346
|
-
] }),
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
]
|
|
1375
|
-
}
|
|
1376
|
-
)
|
|
1377
|
-
] }) : null
|
|
1426
|
+
/* @__PURE__ */ jsxs("div", { style: styles.caseCard, children: [
|
|
1427
|
+
meta.length > 0 && /* @__PURE__ */ jsx("div", { style: styles.metaRow, children: meta.map((item) => /* @__PURE__ */ jsxs("div", { style: styles.metaCol, children: [
|
|
1428
|
+
/* @__PURE__ */ jsx("span", { style: styles.metaLabel, children: item.label }),
|
|
1429
|
+
/* @__PURE__ */ jsx("span", { style: styles.metaValue, children: item.value })
|
|
1430
|
+
] }, item.key)) }),
|
|
1431
|
+
hasActions && /* @__PURE__ */ jsxs("div", { style: styles.actions, children: [
|
|
1432
|
+
hasDicom && onOpenDicom && /* @__PURE__ */ jsxs(
|
|
1433
|
+
"button",
|
|
1434
|
+
{
|
|
1435
|
+
onClick: onOpenDicom,
|
|
1436
|
+
style: styles.dicomButton,
|
|
1437
|
+
type: "button",
|
|
1438
|
+
"aria-label": "View DICOM study",
|
|
1439
|
+
children: [
|
|
1440
|
+
/* @__PURE__ */ jsx(DicomIcon, { size: 18, color: COLOR.primary }),
|
|
1441
|
+
/* @__PURE__ */ jsx("span", { children: "View DICOM" })
|
|
1442
|
+
]
|
|
1443
|
+
}
|
|
1444
|
+
),
|
|
1445
|
+
onOpenSettings && /* @__PURE__ */ jsx(
|
|
1446
|
+
"button",
|
|
1447
|
+
{
|
|
1448
|
+
onClick: onOpenSettings,
|
|
1449
|
+
style: styles.settingsIconButton,
|
|
1450
|
+
type: "button",
|
|
1451
|
+
"aria-label": "Open channel settings",
|
|
1452
|
+
title: "Settings",
|
|
1453
|
+
children: /* @__PURE__ */ jsx(SettingsIcon, { size: 18, color: COLOR.neutral600 })
|
|
1454
|
+
}
|
|
1455
|
+
)
|
|
1456
|
+
] })
|
|
1457
|
+
] })
|
|
1378
1458
|
] });
|
|
1379
1459
|
}
|
|
1380
1460
|
var styles = {
|
|
1381
1461
|
container: {
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
backgroundColor: COLOR.
|
|
1462
|
+
display: "flex",
|
|
1463
|
+
flexDirection: "column",
|
|
1464
|
+
backgroundColor: COLOR.primaryBg,
|
|
1465
|
+
borderBottom: `1px solid ${COLOR.neutral200}`
|
|
1385
1466
|
},
|
|
1467
|
+
// Optional name row, only when `hideName` is false (compact-inbox path)
|
|
1386
1468
|
nameRow: {
|
|
1387
1469
|
display: "flex",
|
|
1388
1470
|
alignItems: "center",
|
|
1389
|
-
gap: SPACE.S2
|
|
1471
|
+
gap: SPACE.S2,
|
|
1472
|
+
padding: `${SPACE.S3} ${SPACE.S4} ${SPACE.S2}`,
|
|
1473
|
+
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
1474
|
+
backgroundColor: COLOR.white
|
|
1390
1475
|
},
|
|
1391
1476
|
backButton: {
|
|
1392
1477
|
width: SIZE.controlIcon,
|
|
@@ -1403,65 +1488,90 @@ var styles = {
|
|
|
1403
1488
|
},
|
|
1404
1489
|
nameText: {
|
|
1405
1490
|
fontSize: FONT_SIZE.lg,
|
|
1406
|
-
fontWeight: FONT_WEIGHT.
|
|
1491
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1407
1492
|
color: COLOR.neutral900,
|
|
1408
1493
|
lineHeight: LINE_HEIGHT.tight,
|
|
1494
|
+
letterSpacing: "-0.01em",
|
|
1409
1495
|
minWidth: 0,
|
|
1410
1496
|
overflow: "hidden",
|
|
1411
1497
|
textOverflow: "ellipsis",
|
|
1412
1498
|
whiteSpace: "nowrap"
|
|
1413
1499
|
},
|
|
1500
|
+
// Case card: meta columns flowing in a wrap-row, actions stacked
|
|
1501
|
+
// below. Each meta column is a small label-above-value pair so the
|
|
1502
|
+
// user can scan field names quickly without a legend.
|
|
1503
|
+
caseCard: {
|
|
1504
|
+
display: "flex",
|
|
1505
|
+
flexDirection: "column",
|
|
1506
|
+
gap: SPACE.S3,
|
|
1507
|
+
padding: `${SPACE.S3} ${SPACE.S5}`
|
|
1508
|
+
},
|
|
1509
|
+
// Wrap-row of stacked label/value columns. Compact column gap keeps
|
|
1510
|
+
// the row dense without crowding; row gap kicks in when columns
|
|
1511
|
+
// wrap to a second line on narrow popups.
|
|
1414
1512
|
metaRow: {
|
|
1415
1513
|
display: "flex",
|
|
1416
1514
|
flexWrap: "wrap",
|
|
1417
|
-
columnGap: SPACE.
|
|
1418
|
-
rowGap: SPACE.
|
|
1419
|
-
|
|
1515
|
+
columnGap: SPACE.S5,
|
|
1516
|
+
rowGap: SPACE.S2,
|
|
1517
|
+
minWidth: 0
|
|
1420
1518
|
},
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1519
|
+
metaCol: {
|
|
1520
|
+
display: "flex",
|
|
1521
|
+
flexDirection: "column",
|
|
1522
|
+
gap: "2px",
|
|
1523
|
+
minWidth: 0
|
|
1425
1524
|
},
|
|
1426
1525
|
metaLabel: {
|
|
1526
|
+
fontSize: "11px",
|
|
1527
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1528
|
+
letterSpacing: "0.06em",
|
|
1529
|
+
textTransform: "uppercase",
|
|
1427
1530
|
color: COLOR.neutral500,
|
|
1428
|
-
|
|
1531
|
+
whiteSpace: "nowrap"
|
|
1429
1532
|
},
|
|
1430
1533
|
metaValue: {
|
|
1431
|
-
|
|
1534
|
+
fontSize: FONT_SIZE.sm,
|
|
1535
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
1536
|
+
color: COLOR.neutral900,
|
|
1537
|
+
whiteSpace: "nowrap",
|
|
1538
|
+
overflow: "hidden",
|
|
1539
|
+
textOverflow: "ellipsis",
|
|
1540
|
+
maxWidth: "180px"
|
|
1432
1541
|
},
|
|
1433
1542
|
actions: {
|
|
1434
1543
|
display: "flex",
|
|
1435
1544
|
gap: SPACE.S2,
|
|
1436
|
-
|
|
1545
|
+
flexShrink: 0
|
|
1437
1546
|
},
|
|
1438
1547
|
dicomButton: {
|
|
1439
1548
|
display: "inline-flex",
|
|
1440
1549
|
alignItems: "center",
|
|
1441
1550
|
gap: SPACE.S2,
|
|
1442
1551
|
minHeight: SIZE.control,
|
|
1443
|
-
padding: `${SPACE.S2}
|
|
1552
|
+
padding: `${SPACE.S2} 14px`,
|
|
1444
1553
|
fontSize: FONT_SIZE.sm,
|
|
1445
|
-
fontWeight: FONT_WEIGHT.
|
|
1446
|
-
color: COLOR.
|
|
1447
|
-
backgroundColor: COLOR.
|
|
1448
|
-
border:
|
|
1449
|
-
borderRadius: RADIUS.
|
|
1554
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
1555
|
+
color: COLOR.primary,
|
|
1556
|
+
backgroundColor: COLOR.white,
|
|
1557
|
+
border: `1.5px solid ${COLOR.primary}`,
|
|
1558
|
+
borderRadius: RADIUS.lg,
|
|
1450
1559
|
cursor: "pointer"
|
|
1451
1560
|
},
|
|
1452
|
-
|
|
1561
|
+
// Settings is icon-only (40x40 tile) since it's a secondary action
|
|
1562
|
+
// and View DICOM already carries a label.
|
|
1563
|
+
settingsIconButton: {
|
|
1564
|
+
width: SIZE.control,
|
|
1565
|
+
height: SIZE.control,
|
|
1453
1566
|
display: "inline-flex",
|
|
1454
1567
|
alignItems: "center",
|
|
1455
|
-
|
|
1456
|
-
minHeight: SIZE.control,
|
|
1457
|
-
padding: `${SPACE.S2} ${SPACE.S4}`,
|
|
1458
|
-
fontSize: FONT_SIZE.sm,
|
|
1459
|
-
fontWeight: FONT_WEIGHT.medium,
|
|
1460
|
-
color: COLOR.neutral700,
|
|
1568
|
+
justifyContent: "center",
|
|
1461
1569
|
backgroundColor: COLOR.white,
|
|
1462
|
-
border: `1px solid ${COLOR.
|
|
1463
|
-
borderRadius: RADIUS.
|
|
1464
|
-
|
|
1570
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1571
|
+
borderRadius: RADIUS.lg,
|
|
1572
|
+
color: COLOR.neutral600,
|
|
1573
|
+
cursor: "pointer",
|
|
1574
|
+
flexShrink: 0
|
|
1465
1575
|
}
|
|
1466
1576
|
};
|
|
1467
1577
|
function ReplyQuoteBlock({
|
|
@@ -1470,10 +1580,10 @@ function ReplyQuoteBlock({
|
|
|
1470
1580
|
onClick,
|
|
1471
1581
|
className
|
|
1472
1582
|
}) {
|
|
1473
|
-
const baseBg = inOwnBubble ? "rgba(255,255,255,0.
|
|
1583
|
+
const baseBg = inOwnBubble ? "rgba(255,255,255,0.22)" : COLOR.white;
|
|
1474
1584
|
const barColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1475
1585
|
const nameColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1476
|
-
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.
|
|
1586
|
+
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.9)" : COLOR.neutral700;
|
|
1477
1587
|
const preview = renderSnapshotPreview(snapshot);
|
|
1478
1588
|
return /* @__PURE__ */ jsxs(
|
|
1479
1589
|
"div",
|
|
@@ -1845,43 +1955,50 @@ var styles4 = {
|
|
|
1845
1955
|
position: "relative",
|
|
1846
1956
|
display: "inline-block"
|
|
1847
1957
|
},
|
|
1958
|
+
// Pill-shaped trigger matching the prototype's `.nc-msg-act` style —
|
|
1959
|
+
// always visible (touch-friendly) rather than hover-only.
|
|
1848
1960
|
trigger: {
|
|
1849
|
-
|
|
1850
|
-
height: SIZE.controlIcon,
|
|
1851
|
-
display: "flex",
|
|
1961
|
+
display: "inline-flex",
|
|
1852
1962
|
alignItems: "center",
|
|
1853
1963
|
justifyContent: "center",
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1964
|
+
width: "32px",
|
|
1965
|
+
height: "32px",
|
|
1966
|
+
backgroundColor: COLOR.white,
|
|
1967
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1968
|
+
borderRadius: "999px",
|
|
1857
1969
|
cursor: "pointer",
|
|
1858
|
-
color: COLOR.neutral600
|
|
1970
|
+
color: COLOR.neutral600,
|
|
1971
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
1859
1972
|
},
|
|
1860
1973
|
menu: {
|
|
1861
1974
|
position: "fixed",
|
|
1862
|
-
minWidth: "
|
|
1975
|
+
minWidth: "200px",
|
|
1863
1976
|
backgroundColor: COLOR.white,
|
|
1864
|
-
border: `1px solid ${COLOR.
|
|
1865
|
-
borderRadius: RADIUS.
|
|
1977
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
1978
|
+
borderRadius: RADIUS.lg,
|
|
1866
1979
|
boxShadow: SHADOW.popover,
|
|
1867
|
-
padding:
|
|
1980
|
+
padding: "6px",
|
|
1981
|
+
display: "flex",
|
|
1982
|
+
flexDirection: "column",
|
|
1983
|
+
gap: "2px",
|
|
1868
1984
|
// Above the floating popup (z-index dialog) but below any future modal.
|
|
1869
1985
|
zIndex: Z_INDEX.menu
|
|
1870
1986
|
},
|
|
1871
1987
|
item: {
|
|
1872
1988
|
display: "flex",
|
|
1873
1989
|
alignItems: "center",
|
|
1874
|
-
gap: SPACE.
|
|
1990
|
+
gap: SPACE.S2,
|
|
1875
1991
|
width: "100%",
|
|
1876
1992
|
minHeight: SIZE.control,
|
|
1877
|
-
padding:
|
|
1993
|
+
padding: `10px ${SPACE.S3}`,
|
|
1878
1994
|
fontSize: FONT_SIZE.sm,
|
|
1879
|
-
color: COLOR.
|
|
1995
|
+
color: COLOR.neutral700,
|
|
1880
1996
|
backgroundColor: "transparent",
|
|
1881
1997
|
border: "none",
|
|
1882
|
-
borderRadius: RADIUS.
|
|
1998
|
+
borderRadius: RADIUS.md,
|
|
1883
1999
|
cursor: "pointer",
|
|
1884
|
-
textAlign: "left"
|
|
2000
|
+
textAlign: "left",
|
|
2001
|
+
fontFamily: "inherit"
|
|
1885
2002
|
},
|
|
1886
2003
|
itemDisabled: {
|
|
1887
2004
|
color: COLOR.neutral400,
|
|
@@ -1995,71 +2112,116 @@ function MessageBubble({
|
|
|
1995
2112
|
},
|
|
1996
2113
|
children: [
|
|
1997
2114
|
isOwn && actionsSlot,
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
"div",
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
message.type === "image" && /* @__PURE__ */ jsx(ImageContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2025
|
-
message.type === "file" && /* @__PURE__ */ jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2026
|
-
message.type === "deep_link" && /* @__PURE__ */ jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
2027
|
-
/* @__PURE__ */ jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
2028
|
-
isOwn && message.status === "sending" && /* @__PURE__ */ jsxs("div", { style: styles5.statusRow, children: [
|
|
2029
|
-
/* @__PURE__ */ jsx(Spinner, { size: 12, color: "rgba(255,255,255,0.85)" }),
|
|
2030
|
-
/* @__PURE__ */ jsx("span", { style: styles5.statusText, children: "Sending\u2026" })
|
|
2031
|
-
] }),
|
|
2032
|
-
isOwn && message.status === "failed" && /* @__PURE__ */ jsxs("div", { style: styles5.statusRow, children: [
|
|
2033
|
-
/* @__PURE__ */ jsx(AlertIcon, { size: 12, color: "#fecaca" }),
|
|
2034
|
-
/* @__PURE__ */ jsx("span", { style: styles5.statusText, children: "Not sent" }),
|
|
2035
|
-
onRetry && /* @__PURE__ */ jsx(
|
|
2036
|
-
"button",
|
|
2115
|
+
/* @__PURE__ */ jsxs("div", { style: styles5.bubbleWrapper, children: [
|
|
2116
|
+
!isOwn && /* @__PURE__ */ jsxs("div", { style: styles5.authorRow, children: [
|
|
2117
|
+
/* @__PURE__ */ jsx(
|
|
2118
|
+
"span",
|
|
2119
|
+
{
|
|
2120
|
+
style: {
|
|
2121
|
+
...styles5.authorAvatar,
|
|
2122
|
+
backgroundColor: roleColor(message.senderRole)
|
|
2123
|
+
},
|
|
2124
|
+
"aria-hidden": "true",
|
|
2125
|
+
children: computeInitials(message.senderName)
|
|
2126
|
+
}
|
|
2127
|
+
),
|
|
2128
|
+
/* @__PURE__ */ jsx("span", { style: styles5.authorName, children: message.senderName }),
|
|
2129
|
+
/* @__PURE__ */ jsx(RoleBadge, { role: message.senderRole })
|
|
2130
|
+
] }),
|
|
2131
|
+
/* @__PURE__ */ jsxs(
|
|
2132
|
+
"div",
|
|
2133
|
+
{
|
|
2134
|
+
style: {
|
|
2135
|
+
...styles5.bubble,
|
|
2136
|
+
...isOwn ? styles5.ownBubble : styles5.otherBubble
|
|
2137
|
+
},
|
|
2138
|
+
children: [
|
|
2139
|
+
message.isPinned && /* @__PURE__ */ jsxs(
|
|
2140
|
+
"div",
|
|
2037
2141
|
{
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
children:
|
|
2142
|
+
style: {
|
|
2143
|
+
...styles5.pinnedBadge,
|
|
2144
|
+
...isOwn ? styles5.pinnedBadgeOwn : styles5.pinnedBadgeOther
|
|
2145
|
+
},
|
|
2146
|
+
children: [
|
|
2147
|
+
/* @__PURE__ */ jsx(PinIcon, { size: 12 }),
|
|
2148
|
+
/* @__PURE__ */ jsx("span", { children: "Pinned" })
|
|
2149
|
+
]
|
|
2043
2150
|
}
|
|
2044
|
-
)
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2151
|
+
),
|
|
2152
|
+
message.replyToSnapshot && /* @__PURE__ */ jsx(
|
|
2153
|
+
ReplyQuoteBlock,
|
|
2154
|
+
{
|
|
2155
|
+
snapshot: message.replyToSnapshot,
|
|
2156
|
+
inOwnBubble: isOwn,
|
|
2157
|
+
onClick: onReplyJumpTo
|
|
2158
|
+
}
|
|
2159
|
+
),
|
|
2160
|
+
message.type === "text" && /* @__PURE__ */ jsx(TextContent, { body: message.body, onDeepLinkClick }),
|
|
2161
|
+
message.type === "audio" && /* @__PURE__ */ jsx(AudioContent, { mediaUrl: message.mediaUrl, duration: message.mediaDuration }),
|
|
2162
|
+
message.type === "image" && /* @__PURE__ */ jsx(ImageContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2163
|
+
message.type === "file" && /* @__PURE__ */ jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2164
|
+
message.type === "deep_link" && /* @__PURE__ */ jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
2165
|
+
/* @__PURE__ */ jsxs("div", { style: styles5.bubbleFoot, children: [
|
|
2166
|
+
/* @__PURE__ */ jsx("span", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
2167
|
+
isOwn && message.status === "sending" && /* @__PURE__ */ jsxs("span", { style: styles5.footStatus, children: [
|
|
2168
|
+
/* @__PURE__ */ jsx(Spinner, { size: 11, color: "rgba(255,255,255,0.85)" }),
|
|
2169
|
+
/* @__PURE__ */ jsx("span", { children: "Sending\u2026" })
|
|
2170
|
+
] }),
|
|
2171
|
+
isOwn && message.status === "failed" && /* @__PURE__ */ jsxs("span", { style: styles5.footStatusFailed, children: [
|
|
2172
|
+
/* @__PURE__ */ jsx(AlertIcon, { size: 11, color: "#fecaca" }),
|
|
2173
|
+
/* @__PURE__ */ jsx("span", { children: "Not sent" }),
|
|
2174
|
+
onRetry && /* @__PURE__ */ jsx(
|
|
2175
|
+
"button",
|
|
2176
|
+
{
|
|
2177
|
+
type: "button",
|
|
2178
|
+
onClick: () => onRetry(message.id),
|
|
2179
|
+
style: styles5.retryButton,
|
|
2180
|
+
"aria-label": "Retry sending message",
|
|
2181
|
+
children: "Retry"
|
|
2182
|
+
}
|
|
2183
|
+
)
|
|
2184
|
+
] }),
|
|
2185
|
+
showSeenBy && isOwn && !message.status && /* @__PURE__ */ jsx(
|
|
2186
|
+
SeenByIndicator,
|
|
2187
|
+
{
|
|
2188
|
+
readBy: message.readBy ?? [],
|
|
2189
|
+
participants,
|
|
2190
|
+
currentUserId,
|
|
2191
|
+
senderId: message.senderId
|
|
2192
|
+
}
|
|
2193
|
+
)
|
|
2194
|
+
] })
|
|
2195
|
+
]
|
|
2196
|
+
}
|
|
2197
|
+
)
|
|
2198
|
+
] }),
|
|
2058
2199
|
!isOwn && actionsSlot
|
|
2059
2200
|
]
|
|
2060
2201
|
}
|
|
2061
2202
|
);
|
|
2062
2203
|
}
|
|
2204
|
+
function computeInitials(name) {
|
|
2205
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("") || "?";
|
|
2206
|
+
}
|
|
2207
|
+
function roleColor(role) {
|
|
2208
|
+
switch (role) {
|
|
2209
|
+
case "radiologist":
|
|
2210
|
+
return "#4f46e5";
|
|
2211
|
+
// indigo (blue-leaning)
|
|
2212
|
+
case "lab":
|
|
2213
|
+
return "#2563eb";
|
|
2214
|
+
// brand blue
|
|
2215
|
+
case "physician":
|
|
2216
|
+
return "#0284c7";
|
|
2217
|
+
// sky
|
|
2218
|
+
case "admin":
|
|
2219
|
+
return "#64748b";
|
|
2220
|
+
// slate (muted)
|
|
2221
|
+
default:
|
|
2222
|
+
return "#6b7280";
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2063
2225
|
function TextContent({ body, onDeepLinkClick }) {
|
|
2064
2226
|
if (body.includes(DEEP_LINK_PREFIX)) {
|
|
2065
2227
|
const parts = body.split(new RegExp(`(${escapeRegex2(DEEP_LINK_PREFIX)}[\\w/.-]+)`, "g"));
|
|
@@ -2121,19 +2283,13 @@ function DeepLinkContent({
|
|
|
2121
2283
|
);
|
|
2122
2284
|
}
|
|
2123
2285
|
function SystemBubble({ message }) {
|
|
2124
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsx("div", { style: styles5.systemWrapper, children: /* @__PURE__ */ jsxs("span", { style: styles5.systemPill, children: [
|
|
2125
2287
|
/* @__PURE__ */ jsx("span", { children: message.body }),
|
|
2126
2288
|
/* @__PURE__ */ jsx("span", { style: styles5.systemTime, children: formatTime(message.insertedAt) })
|
|
2127
|
-
] });
|
|
2289
|
+
] }) });
|
|
2128
2290
|
}
|
|
2129
2291
|
function RoleBadge({ role }) {
|
|
2130
|
-
|
|
2131
|
-
radiologist: "#7c3aed",
|
|
2132
|
-
lab: "#2563eb",
|
|
2133
|
-
physician: "#059669",
|
|
2134
|
-
admin: "#dc2626"
|
|
2135
|
-
};
|
|
2136
|
-
return /* @__PURE__ */ jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: ROLE_LABELS[role] ?? role });
|
|
2292
|
+
return /* @__PURE__ */ jsx("span", { style: { ...styles5.roleBadge, backgroundColor: roleColor(role) }, children: ROLE_LABELS[role] ?? role });
|
|
2137
2293
|
}
|
|
2138
2294
|
function formatTime(iso) {
|
|
2139
2295
|
try {
|
|
@@ -2155,89 +2311,134 @@ var styles5 = {
|
|
|
2155
2311
|
display: "flex",
|
|
2156
2312
|
alignItems: "flex-end",
|
|
2157
2313
|
gap: SPACE.S1,
|
|
2158
|
-
marginBottom: SPACE.
|
|
2314
|
+
marginBottom: SPACE.S3,
|
|
2159
2315
|
paddingLeft: SPACE.S4,
|
|
2160
2316
|
paddingRight: SPACE.S4
|
|
2161
2317
|
},
|
|
2162
2318
|
bubbleWrapper: {
|
|
2163
2319
|
position: "relative",
|
|
2164
|
-
maxWidth: "
|
|
2320
|
+
maxWidth: "78%",
|
|
2321
|
+
display: "flex",
|
|
2322
|
+
flexDirection: "column",
|
|
2323
|
+
gap: "4px"
|
|
2165
2324
|
},
|
|
2166
2325
|
actionsSlot: {
|
|
2167
2326
|
flexShrink: 0,
|
|
2168
2327
|
alignSelf: "flex-end"
|
|
2169
2328
|
},
|
|
2329
|
+
// Author row above the bubble — only rendered for others' messages.
|
|
2330
|
+
authorRow: {
|
|
2331
|
+
display: "flex",
|
|
2332
|
+
alignItems: "center",
|
|
2333
|
+
gap: SPACE.S2
|
|
2334
|
+
},
|
|
2335
|
+
authorAvatar: {
|
|
2336
|
+
width: "36px",
|
|
2337
|
+
height: "36px",
|
|
2338
|
+
borderRadius: "50%",
|
|
2339
|
+
color: COLOR.white,
|
|
2340
|
+
fontSize: FONT_SIZE.sm,
|
|
2341
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2342
|
+
display: "flex",
|
|
2343
|
+
alignItems: "center",
|
|
2344
|
+
justifyContent: "center",
|
|
2345
|
+
flexShrink: 0,
|
|
2346
|
+
letterSpacing: "0.02em"
|
|
2347
|
+
},
|
|
2348
|
+
authorName: {
|
|
2349
|
+
fontSize: FONT_SIZE.sm,
|
|
2350
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
2351
|
+
color: COLOR.neutral700,
|
|
2352
|
+
overflow: "hidden",
|
|
2353
|
+
textOverflow: "ellipsis",
|
|
2354
|
+
whiteSpace: "nowrap",
|
|
2355
|
+
minWidth: 0
|
|
2356
|
+
},
|
|
2170
2357
|
bubble: {
|
|
2171
2358
|
padding: `${SPACE.S3} ${SPACE.S4}`,
|
|
2172
|
-
borderRadius:
|
|
2173
|
-
wordBreak: "break-word"
|
|
2359
|
+
borderRadius: "18px",
|
|
2360
|
+
wordBreak: "break-word",
|
|
2361
|
+
border: "1px solid transparent"
|
|
2174
2362
|
},
|
|
2175
2363
|
ownBubble: {
|
|
2176
2364
|
backgroundColor: COLOR.primary,
|
|
2177
2365
|
color: COLOR.white,
|
|
2178
|
-
|
|
2366
|
+
borderColor: COLOR.primary,
|
|
2367
|
+
borderBottomRightRadius: "6px"
|
|
2179
2368
|
},
|
|
2180
2369
|
otherBubble: {
|
|
2181
2370
|
backgroundColor: COLOR.neutral100,
|
|
2182
2371
|
color: COLOR.neutral900,
|
|
2183
|
-
|
|
2372
|
+
borderColor: COLOR.neutral200,
|
|
2373
|
+
borderBottomLeftRadius: "6px"
|
|
2184
2374
|
},
|
|
2185
2375
|
pinnedBadge: {
|
|
2186
2376
|
display: "inline-flex",
|
|
2187
2377
|
alignItems: "center",
|
|
2188
|
-
gap:
|
|
2189
|
-
fontSize:
|
|
2190
|
-
fontWeight: FONT_WEIGHT.
|
|
2191
|
-
marginBottom: SPACE.
|
|
2192
|
-
|
|
2378
|
+
gap: "4px",
|
|
2379
|
+
fontSize: "11px",
|
|
2380
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2381
|
+
marginBottom: SPACE.S2,
|
|
2382
|
+
padding: `2px ${SPACE.S2}`,
|
|
2383
|
+
borderRadius: "999px",
|
|
2384
|
+
textTransform: "uppercase",
|
|
2385
|
+
letterSpacing: "0.05em"
|
|
2193
2386
|
},
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
gap: SPACE.S2,
|
|
2198
|
-
marginBottom: SPACE.S1
|
|
2387
|
+
pinnedBadgeOther: {
|
|
2388
|
+
color: "#b8680f",
|
|
2389
|
+
backgroundColor: "#fff7e0"
|
|
2199
2390
|
},
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
color: COLOR.neutral700
|
|
2391
|
+
pinnedBadgeOwn: {
|
|
2392
|
+
color: "#fff4d6",
|
|
2393
|
+
backgroundColor: "rgba(255, 255, 255, 0.2)"
|
|
2204
2394
|
},
|
|
2205
2395
|
roleBadge: {
|
|
2206
|
-
fontSize:
|
|
2207
|
-
fontWeight: FONT_WEIGHT.
|
|
2208
|
-
padding:
|
|
2209
|
-
borderRadius: RADIUS.sm
|
|
2396
|
+
fontSize: "10px",
|
|
2397
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2398
|
+
padding: "2px 7px",
|
|
2399
|
+
borderRadius: RADIUS.sm,
|
|
2400
|
+
textTransform: "uppercase",
|
|
2401
|
+
letterSpacing: "0.06em",
|
|
2402
|
+
color: COLOR.white,
|
|
2403
|
+
flexShrink: 0
|
|
2210
2404
|
},
|
|
2211
2405
|
textBody: {
|
|
2212
2406
|
margin: 0,
|
|
2213
2407
|
fontSize: FONT_SIZE.md,
|
|
2214
|
-
lineHeight:
|
|
2408
|
+
lineHeight: 1.5
|
|
2409
|
+
},
|
|
2410
|
+
bubbleFoot: {
|
|
2411
|
+
display: "flex",
|
|
2412
|
+
alignItems: "center",
|
|
2413
|
+
justifyContent: "flex-end",
|
|
2414
|
+
gap: SPACE.S2,
|
|
2415
|
+
marginTop: SPACE.S2,
|
|
2416
|
+
fontSize: "11px",
|
|
2417
|
+
opacity: 0.85
|
|
2215
2418
|
},
|
|
2216
2419
|
timestamp: {
|
|
2217
|
-
fontSize:
|
|
2420
|
+
fontSize: "11px",
|
|
2218
2421
|
color: "inherit",
|
|
2219
|
-
|
|
2220
|
-
marginTop: SPACE.S1,
|
|
2221
|
-
textAlign: "right"
|
|
2422
|
+
fontVariantNumeric: "tabular-nums"
|
|
2222
2423
|
},
|
|
2223
|
-
|
|
2224
|
-
display: "flex",
|
|
2424
|
+
footStatus: {
|
|
2425
|
+
display: "inline-flex",
|
|
2225
2426
|
alignItems: "center",
|
|
2226
|
-
gap:
|
|
2227
|
-
|
|
2228
|
-
fontSize: FONT_SIZE.xs,
|
|
2229
|
-
justifyContent: "flex-end",
|
|
2230
|
-
color: "rgba(255, 255, 255, 0.9)"
|
|
2427
|
+
gap: "4px",
|
|
2428
|
+
fontSize: "11px"
|
|
2231
2429
|
},
|
|
2232
|
-
|
|
2233
|
-
|
|
2430
|
+
footStatusFailed: {
|
|
2431
|
+
display: "inline-flex",
|
|
2432
|
+
alignItems: "center",
|
|
2433
|
+
gap: "4px",
|
|
2434
|
+
fontSize: "11px"
|
|
2234
2435
|
},
|
|
2235
2436
|
retryButton: {
|
|
2236
2437
|
background: "transparent",
|
|
2237
2438
|
border: "none",
|
|
2238
2439
|
color: COLOR.white,
|
|
2239
2440
|
fontWeight: FONT_WEIGHT.semibold,
|
|
2240
|
-
fontSize:
|
|
2441
|
+
fontSize: "11px",
|
|
2241
2442
|
textDecoration: "underline",
|
|
2242
2443
|
cursor: "pointer",
|
|
2243
2444
|
padding: `0 ${SPACE.S1}`
|
|
@@ -2300,18 +2501,25 @@ var styles5 = {
|
|
|
2300
2501
|
color: COLOR.neutral500,
|
|
2301
2502
|
fontFamily: "monospace"
|
|
2302
2503
|
},
|
|
2303
|
-
|
|
2504
|
+
systemWrapper: {
|
|
2304
2505
|
display: "flex",
|
|
2305
2506
|
justifyContent: "center",
|
|
2507
|
+
margin: `${SPACE.S2} 0`
|
|
2508
|
+
},
|
|
2509
|
+
systemPill: {
|
|
2510
|
+
display: "inline-flex",
|
|
2306
2511
|
alignItems: "center",
|
|
2307
2512
|
gap: SPACE.S2,
|
|
2308
|
-
padding:
|
|
2309
|
-
|
|
2513
|
+
padding: `5px ${SPACE.S3}`,
|
|
2514
|
+
backgroundColor: COLOR.neutral100,
|
|
2515
|
+
borderRadius: "999px",
|
|
2516
|
+
fontSize: FONT_SIZE.xs,
|
|
2310
2517
|
color: COLOR.neutral500
|
|
2311
2518
|
},
|
|
2312
2519
|
systemTime: {
|
|
2313
|
-
fontSize:
|
|
2314
|
-
color: COLOR.neutral400
|
|
2520
|
+
fontSize: "11px",
|
|
2521
|
+
color: COLOR.neutral400,
|
|
2522
|
+
fontVariantNumeric: "tabular-nums"
|
|
2315
2523
|
}
|
|
2316
2524
|
};
|
|
2317
2525
|
function ChatIllustration({ size = 96 }) {
|
|
@@ -2450,6 +2658,7 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2450
2658
|
const containerRef = useRef(null);
|
|
2451
2659
|
const bottomRef = useRef(null);
|
|
2452
2660
|
const prevMessageCount = useRef(messages.length);
|
|
2661
|
+
const hasInitiallyScrolledRef = useRef(false);
|
|
2453
2662
|
useImperativeHandle(
|
|
2454
2663
|
ref,
|
|
2455
2664
|
() => ({
|
|
@@ -2467,7 +2676,31 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2467
2676
|
}),
|
|
2468
2677
|
[]
|
|
2469
2678
|
);
|
|
2679
|
+
useLayoutEffect(() => {
|
|
2680
|
+
const container = containerRef.current;
|
|
2681
|
+
if (!container || messages.length === 0) return;
|
|
2682
|
+
if (hasInitiallyScrolledRef.current) return;
|
|
2683
|
+
hasInitiallyScrolledRef.current = true;
|
|
2684
|
+
prevMessageCount.current = messages.length;
|
|
2685
|
+
const firstUnread = messages.find(
|
|
2686
|
+
(m) => m.type !== "system" && m.senderId !== currentUserId && !(m.readBy ?? []).includes(currentUserId)
|
|
2687
|
+
);
|
|
2688
|
+
if (firstUnread) {
|
|
2689
|
+
const el = container.querySelector(
|
|
2690
|
+
`[data-message-id="${firstUnread.id}"]`
|
|
2691
|
+
);
|
|
2692
|
+
if (el) {
|
|
2693
|
+
const containerRect = container.getBoundingClientRect();
|
|
2694
|
+
const elRect = el.getBoundingClientRect();
|
|
2695
|
+
const offset = elRect.top - containerRect.top + container.scrollTop;
|
|
2696
|
+
container.scrollTop = Math.max(0, offset - 16);
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
container.scrollTop = container.scrollHeight;
|
|
2701
|
+
}, [messages, currentUserId]);
|
|
2470
2702
|
useEffect(() => {
|
|
2703
|
+
if (!hasInitiallyScrolledRef.current) return;
|
|
2471
2704
|
if (messages.length > prevMessageCount.current) {
|
|
2472
2705
|
const lastMessage = messages[messages.length - 1];
|
|
2473
2706
|
const isOwnMessage = lastMessage?.senderId === currentUserId;
|
|
@@ -2526,7 +2759,11 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2526
2759
|
const showDivider = !!currentBucket && currentBucket !== lastValidBucket;
|
|
2527
2760
|
if (currentBucket) lastValidBucket = currentBucket;
|
|
2528
2761
|
return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
2529
|
-
showDivider && /* @__PURE__ */
|
|
2762
|
+
showDivider && /* @__PURE__ */ jsxs("div", { style: styles6.dayDivider, role: "separator", "aria-label": "Date", children: [
|
|
2763
|
+
/* @__PURE__ */ jsx("span", { style: styles6.dayHr, "aria-hidden": "true" }),
|
|
2764
|
+
/* @__PURE__ */ jsx("span", { style: styles6.dayLabel, children: formatDayDivider(message.insertedAt) }),
|
|
2765
|
+
/* @__PURE__ */ jsx("span", { style: styles6.dayHr, "aria-hidden": "true" })
|
|
2766
|
+
] }),
|
|
2530
2767
|
/* @__PURE__ */ jsx("div", { "data-message-id": message.id, "data-natoe-message-bubble": true, style: styles6.bubbleSlot, children: /* @__PURE__ */ jsx(
|
|
2531
2768
|
MessageBubble,
|
|
2532
2769
|
{
|
|
@@ -2625,23 +2862,32 @@ var styles6 = {
|
|
|
2625
2862
|
},
|
|
2626
2863
|
dayDivider: {
|
|
2627
2864
|
display: "flex",
|
|
2628
|
-
|
|
2629
|
-
|
|
2865
|
+
alignItems: "center",
|
|
2866
|
+
gap: SPACE.S3,
|
|
2867
|
+
margin: `${SPACE.S4} 0 ${SPACE.S3}`,
|
|
2630
2868
|
position: "sticky",
|
|
2631
2869
|
top: SPACE.S1,
|
|
2632
2870
|
zIndex: Z_INDEX.sticky,
|
|
2633
2871
|
pointerEvents: "none"
|
|
2634
2872
|
},
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2873
|
+
dayHr: {
|
|
2874
|
+
flex: 1,
|
|
2875
|
+
height: "1px",
|
|
2876
|
+
backgroundColor: COLOR.neutral200
|
|
2877
|
+
},
|
|
2878
|
+
dayLabel: {
|
|
2879
|
+
flexShrink: 0,
|
|
2880
|
+
fontSize: FONT_SIZE.xs,
|
|
2881
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
2882
|
+
color: COLOR.neutral500,
|
|
2883
|
+
textTransform: "uppercase",
|
|
2884
|
+
letterSpacing: "0.06em",
|
|
2885
|
+
// Subtle pill background so the label is readable when it overlays
|
|
2886
|
+
// bubbles passing under it during sticky scroll. Without this the
|
|
2887
|
+
// hairlines visually run through the text on tinted backgrounds.
|
|
2888
|
+
padding: `2px ${SPACE.S2}`,
|
|
2889
|
+
backgroundColor: COLOR.white,
|
|
2890
|
+
borderRadius: RADIUS.sm
|
|
2645
2891
|
},
|
|
2646
2892
|
bubbleSlot: {
|
|
2647
2893
|
animation: "natoe-colab-message-in 180ms ease-out"
|
|
@@ -2895,11 +3141,11 @@ function MessageInput({
|
|
|
2895
3141
|
{
|
|
2896
3142
|
onClick: () => fileInputRef.current?.click(),
|
|
2897
3143
|
disabled: disabled || isSending,
|
|
2898
|
-
style: styles8.
|
|
3144
|
+
style: styles8.attachButton,
|
|
2899
3145
|
"aria-label": "Attach file",
|
|
2900
3146
|
title: "Attach file",
|
|
2901
3147
|
type: "button",
|
|
2902
|
-
children: /* @__PURE__ */ jsx(AttachIcon, { size: 22, color:
|
|
3148
|
+
children: /* @__PURE__ */ jsx(AttachIcon, { size: 22, color: COLOR.neutral700 })
|
|
2903
3149
|
}
|
|
2904
3150
|
),
|
|
2905
3151
|
/* @__PURE__ */ jsx(
|
|
@@ -2938,7 +3184,7 @@ function MessageInput({
|
|
|
2938
3184
|
style: styles8.textarea
|
|
2939
3185
|
}
|
|
2940
3186
|
),
|
|
2941
|
-
/* @__PURE__ */
|
|
3187
|
+
/* @__PURE__ */ jsxs(
|
|
2942
3188
|
"button",
|
|
2943
3189
|
{
|
|
2944
3190
|
onClick: handleSendText,
|
|
@@ -2947,10 +3193,13 @@ function MessageInput({
|
|
|
2947
3193
|
title: "Send message",
|
|
2948
3194
|
style: {
|
|
2949
3195
|
...styles8.sendButton,
|
|
2950
|
-
opacity: text.trim() ? 1 : 0.
|
|
3196
|
+
opacity: text.trim() ? 1 : 0.5
|
|
2951
3197
|
},
|
|
2952
3198
|
type: "button",
|
|
2953
|
-
children:
|
|
3199
|
+
children: [
|
|
3200
|
+
/* @__PURE__ */ jsx(SendIcon, { size: 20, color: COLOR.white }),
|
|
3201
|
+
/* @__PURE__ */ jsx("span", { style: styles8.sendLabel, children: "Send" })
|
|
3202
|
+
]
|
|
2954
3203
|
}
|
|
2955
3204
|
)
|
|
2956
3205
|
] })
|
|
@@ -3012,46 +3261,64 @@ var styles8 = {
|
|
|
3012
3261
|
inputBar: {
|
|
3013
3262
|
display: "flex",
|
|
3014
3263
|
alignItems: "flex-end",
|
|
3015
|
-
gap:
|
|
3016
|
-
padding: `${SPACE.S3} ${SPACE.
|
|
3017
|
-
},
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3264
|
+
gap: "10px",
|
|
3265
|
+
padding: `${SPACE.S3} ${SPACE.S4} 14px`
|
|
3266
|
+
},
|
|
3267
|
+
// 48px square tile with a 14px corner radius — visually grounds the
|
|
3268
|
+
// attach affordance as part of the composer chrome rather than a stray
|
|
3269
|
+
// round icon button.
|
|
3270
|
+
attachButton: {
|
|
3271
|
+
width: "48px",
|
|
3272
|
+
height: "48px",
|
|
3021
3273
|
display: "flex",
|
|
3022
3274
|
alignItems: "center",
|
|
3023
3275
|
justifyContent: "center",
|
|
3024
|
-
backgroundColor:
|
|
3025
|
-
border:
|
|
3026
|
-
borderRadius:
|
|
3276
|
+
backgroundColor: COLOR.neutral100,
|
|
3277
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3278
|
+
borderRadius: "14px",
|
|
3027
3279
|
cursor: "pointer",
|
|
3028
|
-
flexShrink: 0
|
|
3280
|
+
flexShrink: 0,
|
|
3281
|
+
color: COLOR.neutral700,
|
|
3282
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
3029
3283
|
},
|
|
3030
3284
|
textarea: {
|
|
3031
3285
|
flex: 1,
|
|
3032
|
-
|
|
3286
|
+
minHeight: "48px",
|
|
3287
|
+
maxHeight: "140px",
|
|
3288
|
+
padding: "13px 16px",
|
|
3033
3289
|
fontSize: FONT_SIZE.md,
|
|
3034
3290
|
lineHeight: LINE_HEIGHT.normal,
|
|
3035
|
-
|
|
3036
|
-
|
|
3291
|
+
color: COLOR.neutral900,
|
|
3292
|
+
backgroundColor: COLOR.neutral100,
|
|
3293
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3294
|
+
borderRadius: "14px",
|
|
3037
3295
|
resize: "none",
|
|
3038
3296
|
outline: "none",
|
|
3039
3297
|
fontFamily: "inherit",
|
|
3040
|
-
|
|
3041
|
-
minHeight: SIZE.controlPrimary
|
|
3298
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease"
|
|
3042
3299
|
},
|
|
3300
|
+
// Pill-shaped send: icon + "Send" label. Always labelled (never icon-
|
|
3301
|
+
// only) so the affordance is obvious to first-time users.
|
|
3043
3302
|
sendButton: {
|
|
3044
|
-
|
|
3045
|
-
height: SIZE.controlPrimary,
|
|
3046
|
-
display: "flex",
|
|
3303
|
+
display: "inline-flex",
|
|
3047
3304
|
alignItems: "center",
|
|
3048
|
-
|
|
3305
|
+
gap: "6px",
|
|
3306
|
+
minWidth: "48px",
|
|
3307
|
+
height: "48px",
|
|
3308
|
+
padding: `0 ${SPACE.S4}`,
|
|
3049
3309
|
backgroundColor: COLOR.primary,
|
|
3050
3310
|
color: COLOR.white,
|
|
3051
3311
|
border: "none",
|
|
3052
|
-
borderRadius:
|
|
3312
|
+
borderRadius: "14px",
|
|
3053
3313
|
cursor: "pointer",
|
|
3054
|
-
flexShrink: 0
|
|
3314
|
+
flexShrink: 0,
|
|
3315
|
+
fontFamily: "inherit",
|
|
3316
|
+
fontSize: "15px",
|
|
3317
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
3318
|
+
transition: "opacity 120ms ease, background-color 120ms ease"
|
|
3319
|
+
},
|
|
3320
|
+
sendLabel: {
|
|
3321
|
+
lineHeight: 1
|
|
3055
3322
|
}};
|
|
3056
3323
|
function ParticipantsList({
|
|
3057
3324
|
participants,
|
|
@@ -3108,10 +3375,14 @@ function fallbackName(role) {
|
|
|
3108
3375
|
}
|
|
3109
3376
|
function RoleBadge2({ role }) {
|
|
3110
3377
|
const colors = {
|
|
3111
|
-
radiologist: { bg: "#
|
|
3378
|
+
radiologist: { bg: "#eef2ff", text: "#4f46e5" },
|
|
3379
|
+
// indigo
|
|
3112
3380
|
lab: { bg: "#eff6ff", text: "#2563eb" },
|
|
3113
|
-
|
|
3114
|
-
|
|
3381
|
+
// brand blue
|
|
3382
|
+
physician: { bg: "#e0f2fe", text: "#0284c7" },
|
|
3383
|
+
// sky
|
|
3384
|
+
admin: { bg: "#f1f5f9", text: "#64748b" }
|
|
3385
|
+
// slate
|
|
3115
3386
|
};
|
|
3116
3387
|
const color = colors[role];
|
|
3117
3388
|
return /* @__PURE__ */ jsx("span", { style: { ...styles9.roleBadge, backgroundColor: color.bg, color: color.text }, children: role });
|
|
@@ -3720,45 +3991,6 @@ var styles12 = {
|
|
|
3720
3991
|
letterSpacing: "0.4px"
|
|
3721
3992
|
}
|
|
3722
3993
|
};
|
|
3723
|
-
|
|
3724
|
-
// src/core/styles.ts
|
|
3725
|
-
var FONT_STACK = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
3726
|
-
var ROOT_CLASS = "natoe-colab-root";
|
|
3727
|
-
var GLOBAL_STYLE_ID = "natoe-colab-global-styles";
|
|
3728
|
-
var GLOBAL_CSS = `
|
|
3729
|
-
@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }
|
|
3730
|
-
|
|
3731
|
-
@keyframes natoe-colab-message-in {
|
|
3732
|
-
from { opacity: 0; transform: translateY(4px); }
|
|
3733
|
-
to { opacity: 1; transform: translateY(0); }
|
|
3734
|
-
}
|
|
3735
|
-
|
|
3736
|
-
/* High-contrast adjustments \u2014 older users on OS-level high-contrast mode
|
|
3737
|
-
get heavier borders and stronger text without losing the package look. */
|
|
3738
|
-
@media (prefers-contrast: more) {
|
|
3739
|
-
.${ROOT_CLASS} {
|
|
3740
|
-
color: #000000;
|
|
3741
|
-
}
|
|
3742
|
-
.${ROOT_CLASS} button {
|
|
3743
|
-
outline: 1px solid currentColor;
|
|
3744
|
-
}
|
|
3745
|
-
}
|
|
3746
|
-
|
|
3747
|
-
/* Honour reduced-motion preferences by killing entry animations. */
|
|
3748
|
-
@media (prefers-reduced-motion: reduce) {
|
|
3749
|
-
.${ROOT_CLASS} [data-natoe-message-bubble] {
|
|
3750
|
-
animation: none !important;
|
|
3751
|
-
}
|
|
3752
|
-
}
|
|
3753
|
-
`;
|
|
3754
|
-
function ensureGlobalStyles() {
|
|
3755
|
-
if (typeof document === "undefined") return;
|
|
3756
|
-
if (document.getElementById(GLOBAL_STYLE_ID)) return;
|
|
3757
|
-
const style = document.createElement("style");
|
|
3758
|
-
style.id = GLOBAL_STYLE_ID;
|
|
3759
|
-
style.textContent = GLOBAL_CSS;
|
|
3760
|
-
document.head.appendChild(style);
|
|
3761
|
-
}
|
|
3762
3994
|
ensureGlobalStyles();
|
|
3763
3995
|
function CollabPanel({
|
|
3764
3996
|
orderId,
|
|
@@ -4007,6 +4239,7 @@ function CollabPopup({
|
|
|
4007
4239
|
isOpen,
|
|
4008
4240
|
onClose,
|
|
4009
4241
|
onBack,
|
|
4242
|
+
onMinimize,
|
|
4010
4243
|
initialPosition,
|
|
4011
4244
|
width = 380,
|
|
4012
4245
|
height = 520,
|
|
@@ -4122,35 +4355,48 @@ function CollabPopup({
|
|
|
4122
4355
|
"button",
|
|
4123
4356
|
{
|
|
4124
4357
|
onClick: onBack,
|
|
4125
|
-
style: styles13.
|
|
4126
|
-
"aria-label": "
|
|
4358
|
+
style: styles13.titleSquare,
|
|
4359
|
+
"aria-label": "Back to messages",
|
|
4127
4360
|
title: "Back",
|
|
4128
4361
|
type: "button",
|
|
4129
|
-
children:
|
|
4362
|
+
children: /* @__PURE__ */ jsx(BackIcon, { size: 18, color: COLOR.neutral700 })
|
|
4130
4363
|
}
|
|
4131
4364
|
),
|
|
4132
|
-
/* @__PURE__ */
|
|
4365
|
+
/* @__PURE__ */ jsxs("div", { style: styles13.titleCenter, children: [
|
|
4366
|
+
/* @__PURE__ */ jsx("h2", { id: titleId, style: styles13.patientName, children: patientData.patientName || titleText }),
|
|
4367
|
+
(patientData.labName || patientData.displayOrderId) && /* @__PURE__ */ jsxs("div", { style: styles13.subRow, children: [
|
|
4368
|
+
patientData.labName && /* @__PURE__ */ jsx("span", { children: patientData.labName }),
|
|
4369
|
+
patientData.labName && patientData.displayOrderId && /* @__PURE__ */ jsx("span", { style: styles13.subDot, "aria-hidden": "true", children: "\xB7" }),
|
|
4370
|
+
patientData.displayOrderId && /* @__PURE__ */ jsxs("span", { style: styles13.mono, children: [
|
|
4371
|
+
"#",
|
|
4372
|
+
patientData.displayOrderId.slice(-4)
|
|
4373
|
+
] })
|
|
4374
|
+
] })
|
|
4375
|
+
] }),
|
|
4133
4376
|
/* @__PURE__ */ jsxs("div", { style: styles13.titleActions, children: [
|
|
4134
4377
|
/* @__PURE__ */ jsx(
|
|
4135
4378
|
"button",
|
|
4136
4379
|
{
|
|
4137
|
-
onClick: () =>
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4380
|
+
onClick: () => {
|
|
4381
|
+
if (onMinimize) onMinimize();
|
|
4382
|
+
else setIsMinimized(!isMinimized);
|
|
4383
|
+
},
|
|
4384
|
+
style: styles13.titleSquare,
|
|
4385
|
+
"aria-label": onMinimize ? "Minimize chat" : isMinimized ? "Expand chat" : "Minimize chat",
|
|
4386
|
+
title: onMinimize ? "Minimize" : isMinimized ? "Expand" : "Minimize",
|
|
4141
4387
|
type: "button",
|
|
4142
|
-
children: isMinimized ? /* @__PURE__ */ jsx(
|
|
4388
|
+
children: onMinimize || !isMinimized ? /* @__PURE__ */ jsx(MinimizeIcon, { size: 18, color: COLOR.neutral700 }) : /* @__PURE__ */ jsx(ExpandIcon, { size: 18, color: COLOR.neutral700 })
|
|
4143
4389
|
}
|
|
4144
4390
|
),
|
|
4145
4391
|
/* @__PURE__ */ jsx(
|
|
4146
4392
|
"button",
|
|
4147
4393
|
{
|
|
4148
4394
|
onClick: onClose,
|
|
4149
|
-
style: styles13.
|
|
4395
|
+
style: styles13.titleSquare,
|
|
4150
4396
|
"aria-label": "Close chat",
|
|
4151
4397
|
title: "Close",
|
|
4152
4398
|
type: "button",
|
|
4153
|
-
children: /* @__PURE__ */ jsx(CloseIcon, { size:
|
|
4399
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { size: 18, color: COLOR.neutral700 })
|
|
4154
4400
|
}
|
|
4155
4401
|
)
|
|
4156
4402
|
] })
|
|
@@ -4173,51 +4419,78 @@ var styles13 = {
|
|
|
4173
4419
|
container: {
|
|
4174
4420
|
position: "fixed",
|
|
4175
4421
|
zIndex: Z_INDEX.dialog,
|
|
4176
|
-
borderRadius:
|
|
4177
|
-
boxShadow:
|
|
4422
|
+
borderRadius: "20px",
|
|
4423
|
+
boxShadow: "0 20px 48px rgba(20, 21, 28, 0.16), 0 6px 16px rgba(20, 21, 28, 0.08)",
|
|
4178
4424
|
overflow: "hidden",
|
|
4179
4425
|
display: "flex",
|
|
4180
4426
|
flexDirection: "column",
|
|
4181
4427
|
backgroundColor: COLOR.white,
|
|
4182
|
-
border: `1px solid ${COLOR.
|
|
4428
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
4183
4429
|
transition: "height 0.2s ease",
|
|
4184
4430
|
fontFamily: FONT_STACK
|
|
4185
4431
|
},
|
|
4186
4432
|
titleBar: {
|
|
4187
4433
|
display: "flex",
|
|
4188
|
-
justifyContent: "space-between",
|
|
4189
4434
|
alignItems: "center",
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
backgroundColor: COLOR.
|
|
4435
|
+
gap: SPACE.S2,
|
|
4436
|
+
padding: `10px ${SPACE.S3}`,
|
|
4437
|
+
backgroundColor: COLOR.white,
|
|
4438
|
+
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
4193
4439
|
cursor: "grab",
|
|
4194
4440
|
userSelect: "none",
|
|
4195
4441
|
flexShrink: 0
|
|
4196
4442
|
},
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4443
|
+
titleCenter: {
|
|
4444
|
+
flex: 1,
|
|
4445
|
+
minWidth: 0,
|
|
4446
|
+
display: "flex",
|
|
4447
|
+
flexDirection: "column",
|
|
4448
|
+
gap: "2px"
|
|
4449
|
+
},
|
|
4450
|
+
patientName: {
|
|
4451
|
+
margin: 0,
|
|
4452
|
+
fontSize: FONT_SIZE.lg,
|
|
4453
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
4454
|
+
letterSpacing: "-0.01em",
|
|
4455
|
+
color: COLOR.neutral900,
|
|
4201
4456
|
overflow: "hidden",
|
|
4202
4457
|
textOverflow: "ellipsis",
|
|
4203
4458
|
whiteSpace: "nowrap"
|
|
4204
4459
|
},
|
|
4460
|
+
subRow: {
|
|
4461
|
+
display: "flex",
|
|
4462
|
+
alignItems: "center",
|
|
4463
|
+
gap: SPACE.S2,
|
|
4464
|
+
fontSize: FONT_SIZE.sm,
|
|
4465
|
+
color: COLOR.neutral500,
|
|
4466
|
+
overflow: "hidden",
|
|
4467
|
+
textOverflow: "ellipsis",
|
|
4468
|
+
whiteSpace: "nowrap"
|
|
4469
|
+
},
|
|
4470
|
+
subDot: {
|
|
4471
|
+
color: COLOR.neutral400
|
|
4472
|
+
},
|
|
4473
|
+
mono: {
|
|
4474
|
+
fontFamily: "'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
4475
|
+
fontVariantNumeric: "tabular-nums"
|
|
4476
|
+
},
|
|
4205
4477
|
titleActions: {
|
|
4206
4478
|
display: "flex",
|
|
4207
4479
|
gap: SPACE.S1,
|
|
4208
4480
|
flexShrink: 0
|
|
4209
4481
|
},
|
|
4210
|
-
|
|
4211
|
-
width:
|
|
4212
|
-
height:
|
|
4482
|
+
titleSquare: {
|
|
4483
|
+
width: "36px",
|
|
4484
|
+
height: "36px",
|
|
4213
4485
|
display: "flex",
|
|
4214
4486
|
alignItems: "center",
|
|
4215
4487
|
justifyContent: "center",
|
|
4216
|
-
backgroundColor:
|
|
4217
|
-
border:
|
|
4488
|
+
backgroundColor: COLOR.neutral100,
|
|
4489
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
4218
4490
|
borderRadius: RADIUS.md,
|
|
4219
4491
|
cursor: "pointer",
|
|
4220
|
-
color: COLOR.
|
|
4492
|
+
color: COLOR.neutral700,
|
|
4493
|
+
flexShrink: 0
|
|
4221
4494
|
},
|
|
4222
4495
|
panelWrapper: {
|
|
4223
4496
|
flex: 1,
|
|
@@ -4521,10 +4794,14 @@ function InlineMessageRow({ message }) {
|
|
|
4521
4794
|
}
|
|
4522
4795
|
function RoleDot({ role }) {
|
|
4523
4796
|
const colors = {
|
|
4524
|
-
radiologist: "#
|
|
4797
|
+
radiologist: "#4f46e5",
|
|
4798
|
+
// indigo
|
|
4525
4799
|
lab: "#2563eb",
|
|
4526
|
-
|
|
4527
|
-
|
|
4800
|
+
// brand blue
|
|
4801
|
+
physician: "#0284c7",
|
|
4802
|
+
// sky
|
|
4803
|
+
admin: "#64748b"
|
|
4804
|
+
// slate
|
|
4528
4805
|
};
|
|
4529
4806
|
return /* @__PURE__ */ jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
|
|
4530
4807
|
}
|
|
@@ -4946,6 +5223,10 @@ function ConversationListItem({
|
|
|
4946
5223
|
}) {
|
|
4947
5224
|
const hasUnread = item.unreadCount > 0;
|
|
4948
5225
|
const displayName = item.name || item.patientSnapshot?.patientName || "Unknown";
|
|
5226
|
+
const studyType = item.patientSnapshot?.studyType;
|
|
5227
|
+
const patientId = item.patientSnapshot?.patientId;
|
|
5228
|
+
const showStudyRow = !!(studyType || patientId);
|
|
5229
|
+
const initials = computeInitials2(item.patientSnapshot?.patientName || displayName);
|
|
4949
5230
|
return /* @__PURE__ */ jsxs(
|
|
4950
5231
|
"button",
|
|
4951
5232
|
{
|
|
@@ -4953,15 +5234,11 @@ function ConversationListItem({
|
|
|
4953
5234
|
onClick,
|
|
4954
5235
|
style: {
|
|
4955
5236
|
...styles15.container,
|
|
4956
|
-
...isSelected ? styles15.selected : {}
|
|
4957
|
-
...hasUnread ? styles15.unread : {}
|
|
5237
|
+
...isSelected ? styles15.selected : {}
|
|
4958
5238
|
},
|
|
4959
5239
|
type: "button",
|
|
4960
5240
|
children: [
|
|
4961
|
-
/* @__PURE__ */
|
|
4962
|
-
item.picture ? /* @__PURE__ */ jsx("img", { src: item.picture, alt: "", style: styles15.avatar }) : /* @__PURE__ */ jsx("div", { style: styles15.avatarFallback, children: (displayName).charAt(0).toUpperCase() }),
|
|
4963
|
-
hasUnread && /* @__PURE__ */ jsx("span", { style: styles15.unreadDot })
|
|
4964
|
-
] }),
|
|
5241
|
+
/* @__PURE__ */ jsx("div", { style: styles15.avatarWrapper, children: item.picture ? /* @__PURE__ */ jsx("img", { src: item.picture, alt: "", style: styles15.avatarImg }) : /* @__PURE__ */ jsx("div", { style: styles15.avatarTile, "aria-hidden": "true", children: initials }) }),
|
|
4965
5242
|
/* @__PURE__ */ jsxs("div", { style: styles15.content, children: [
|
|
4966
5243
|
/* @__PURE__ */ jsxs("div", { style: styles15.topRow, children: [
|
|
4967
5244
|
/* @__PURE__ */ jsx(
|
|
@@ -4985,101 +5262,120 @@ function ConversationListItem({
|
|
|
4985
5262
|
}
|
|
4986
5263
|
)
|
|
4987
5264
|
] }),
|
|
5265
|
+
showStudyRow && /* @__PURE__ */ jsxs("div", { style: styles15.studyRow, children: [
|
|
5266
|
+
studyType && /* @__PURE__ */ jsx("span", { style: styles15.studyType, children: studyType }),
|
|
5267
|
+
studyType && patientId && /* @__PURE__ */ jsx("span", { style: styles15.studyDivider, children: "\xB7" }),
|
|
5268
|
+
patientId && /* @__PURE__ */ jsxs("span", { style: styles15.studyId, children: [
|
|
5269
|
+
"MRN ",
|
|
5270
|
+
patientId
|
|
5271
|
+
] })
|
|
5272
|
+
] }),
|
|
4988
5273
|
/* @__PURE__ */ jsxs("div", { style: styles15.bottomRow, children: [
|
|
4989
|
-
/* @__PURE__ */ jsx(
|
|
4990
|
-
|
|
4991
|
-
{
|
|
4992
|
-
style: {
|
|
4993
|
-
...styles15.preview,
|
|
4994
|
-
...hasUnread ? styles15.previewUnread : {}
|
|
4995
|
-
},
|
|
4996
|
-
children: renderLastMessagePreview(item.lastMessage)
|
|
4997
|
-
}
|
|
4998
|
-
),
|
|
4999
|
-
hasUnread && /* @__PURE__ */ jsx("span", { style: styles15.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
5274
|
+
/* @__PURE__ */ jsx(PreviewLine, { message: item.lastMessage, hasUnread }),
|
|
5275
|
+
hasUnread && /* @__PURE__ */ jsx("span", { style: styles15.badge, "aria-label": `${item.unreadCount} unread`, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
5000
5276
|
] })
|
|
5001
5277
|
] })
|
|
5002
5278
|
]
|
|
5003
5279
|
}
|
|
5004
5280
|
);
|
|
5005
5281
|
}
|
|
5006
|
-
function
|
|
5007
|
-
if (!message)
|
|
5008
|
-
|
|
5282
|
+
function PreviewLine({ message, hasUnread }) {
|
|
5283
|
+
if (!message) {
|
|
5284
|
+
return /* @__PURE__ */ jsx("span", { style: styles15.preview, children: "No messages yet" });
|
|
5285
|
+
}
|
|
5286
|
+
if (message.type === "system") {
|
|
5287
|
+
return /* @__PURE__ */ jsx("span", { style: styles15.preview, children: message.body });
|
|
5288
|
+
}
|
|
5289
|
+
const text = previewText(message);
|
|
5290
|
+
const sender = message.senderName ? `${message.senderName.split(" ")[0]}:` : "";
|
|
5291
|
+
return /* @__PURE__ */ jsxs(
|
|
5292
|
+
"span",
|
|
5293
|
+
{
|
|
5294
|
+
style: {
|
|
5295
|
+
...styles15.preview,
|
|
5296
|
+
...hasUnread ? styles15.previewUnread : {}
|
|
5297
|
+
},
|
|
5298
|
+
children: [
|
|
5299
|
+
sender && /* @__PURE__ */ jsxs("span", { style: styles15.previewSender, children: [
|
|
5300
|
+
sender,
|
|
5301
|
+
" "
|
|
5302
|
+
] }),
|
|
5303
|
+
text
|
|
5304
|
+
]
|
|
5305
|
+
}
|
|
5306
|
+
);
|
|
5307
|
+
}
|
|
5308
|
+
function previewText(message) {
|
|
5009
5309
|
switch (message.type) {
|
|
5010
5310
|
case "audio":
|
|
5011
|
-
return
|
|
5311
|
+
return "Voice message";
|
|
5012
5312
|
case "image":
|
|
5013
|
-
return
|
|
5313
|
+
return message.fileName || "Image";
|
|
5014
5314
|
case "file":
|
|
5015
|
-
return
|
|
5315
|
+
return message.fileName || "File";
|
|
5016
5316
|
case "deep_link":
|
|
5017
|
-
return
|
|
5018
|
-
case "system":
|
|
5019
|
-
return message.body;
|
|
5317
|
+
return message.body || "Shared link";
|
|
5020
5318
|
default: {
|
|
5021
5319
|
const body = message.body || "";
|
|
5022
|
-
|
|
5023
|
-
return `${prefix}${preview}`;
|
|
5320
|
+
return body.length > 60 ? `${body.slice(0, 60)}\u2026` : body;
|
|
5024
5321
|
}
|
|
5025
5322
|
}
|
|
5026
5323
|
}
|
|
5324
|
+
function computeInitials2(name) {
|
|
5325
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("") || "?";
|
|
5326
|
+
}
|
|
5027
5327
|
var styles15 = {
|
|
5028
5328
|
container: {
|
|
5029
5329
|
display: "flex",
|
|
5030
|
-
alignItems: "
|
|
5031
|
-
gap:
|
|
5032
|
-
padding: `${SPACE.S3} ${SPACE.S3}`,
|
|
5330
|
+
alignItems: "flex-start",
|
|
5331
|
+
gap: "14px",
|
|
5033
5332
|
width: "100%",
|
|
5333
|
+
padding: `14px ${SPACE.S5}`,
|
|
5334
|
+
minHeight: "84px",
|
|
5034
5335
|
backgroundColor: "transparent",
|
|
5035
5336
|
border: "none",
|
|
5036
|
-
|
|
5337
|
+
borderLeft: "4px solid transparent",
|
|
5037
5338
|
cursor: "pointer",
|
|
5038
|
-
textAlign: "left"
|
|
5339
|
+
textAlign: "left",
|
|
5340
|
+
color: "inherit",
|
|
5341
|
+
fontFamily: "inherit",
|
|
5342
|
+
transition: "background-color 120ms ease"
|
|
5039
5343
|
},
|
|
5040
5344
|
selected: {
|
|
5041
|
-
backgroundColor: COLOR.primaryBg
|
|
5345
|
+
backgroundColor: COLOR.primaryBg,
|
|
5346
|
+
borderLeftColor: COLOR.primary
|
|
5042
5347
|
},
|
|
5043
|
-
unread: {},
|
|
5044
5348
|
avatarWrapper: {
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
height: SIZE.avatar,
|
|
5349
|
+
width: "52px",
|
|
5350
|
+
height: "52px",
|
|
5048
5351
|
flexShrink: 0
|
|
5049
5352
|
},
|
|
5050
|
-
|
|
5051
|
-
width:
|
|
5052
|
-
height:
|
|
5053
|
-
borderRadius: RADIUS.
|
|
5054
|
-
objectFit: "cover"
|
|
5353
|
+
avatarImg: {
|
|
5354
|
+
width: "52px",
|
|
5355
|
+
height: "52px",
|
|
5356
|
+
borderRadius: RADIUS.xl,
|
|
5357
|
+
objectFit: "cover",
|
|
5358
|
+
boxShadow: "inset 0 -2px 0 rgba(0, 0, 0, 0.08)"
|
|
5055
5359
|
},
|
|
5056
|
-
|
|
5057
|
-
width:
|
|
5058
|
-
height:
|
|
5059
|
-
borderRadius: RADIUS.
|
|
5060
|
-
backgroundColor: COLOR.
|
|
5360
|
+
avatarTile: {
|
|
5361
|
+
width: "52px",
|
|
5362
|
+
height: "52px",
|
|
5363
|
+
borderRadius: RADIUS.xl,
|
|
5364
|
+
backgroundColor: COLOR.primary,
|
|
5365
|
+
color: COLOR.white,
|
|
5061
5366
|
display: "flex",
|
|
5062
5367
|
alignItems: "center",
|
|
5063
5368
|
justifyContent: "center",
|
|
5064
|
-
fontSize: FONT_SIZE.
|
|
5065
|
-
fontWeight: FONT_WEIGHT.
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
unreadDot: {
|
|
5069
|
-
position: "absolute",
|
|
5070
|
-
top: "0",
|
|
5071
|
-
left: "0",
|
|
5072
|
-
width: SIZE.dot,
|
|
5073
|
-
height: SIZE.dot,
|
|
5074
|
-
borderRadius: RADIUS.full,
|
|
5075
|
-
backgroundColor: COLOR.primary,
|
|
5076
|
-
border: `2px solid ${COLOR.white}`
|
|
5369
|
+
fontSize: FONT_SIZE.lg,
|
|
5370
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
5371
|
+
letterSpacing: "0.02em",
|
|
5372
|
+
boxShadow: "inset 0 -2px 0 rgba(0, 0, 0, 0.08)"
|
|
5077
5373
|
},
|
|
5078
5374
|
content: {
|
|
5079
5375
|
flex: 1,
|
|
5080
5376
|
display: "flex",
|
|
5081
5377
|
flexDirection: "column",
|
|
5082
|
-
gap: "
|
|
5378
|
+
gap: "3px",
|
|
5083
5379
|
minWidth: 0
|
|
5084
5380
|
},
|
|
5085
5381
|
topRow: {
|
|
@@ -5104,123 +5400,191 @@ var styles15 = {
|
|
|
5104
5400
|
time: {
|
|
5105
5401
|
fontSize: FONT_SIZE.xs,
|
|
5106
5402
|
color: COLOR.neutral500,
|
|
5403
|
+
fontVariantNumeric: "tabular-nums",
|
|
5107
5404
|
flexShrink: 0
|
|
5108
5405
|
},
|
|
5109
5406
|
timeUnread: {
|
|
5110
5407
|
color: COLOR.primary,
|
|
5111
5408
|
fontWeight: FONT_WEIGHT.semibold
|
|
5112
5409
|
},
|
|
5410
|
+
studyRow: {
|
|
5411
|
+
display: "flex",
|
|
5412
|
+
alignItems: "center",
|
|
5413
|
+
gap: SPACE.S2,
|
|
5414
|
+
minWidth: 0
|
|
5415
|
+
},
|
|
5416
|
+
studyType: {
|
|
5417
|
+
fontSize: FONT_SIZE.sm,
|
|
5418
|
+
color: COLOR.neutral500,
|
|
5419
|
+
overflow: "hidden",
|
|
5420
|
+
textOverflow: "ellipsis",
|
|
5421
|
+
whiteSpace: "nowrap"
|
|
5422
|
+
},
|
|
5423
|
+
studyDivider: {
|
|
5424
|
+
fontSize: FONT_SIZE.sm,
|
|
5425
|
+
color: COLOR.neutral400,
|
|
5426
|
+
flexShrink: 0
|
|
5427
|
+
},
|
|
5428
|
+
studyId: {
|
|
5429
|
+
fontSize: FONT_SIZE.sm,
|
|
5430
|
+
color: COLOR.neutral500,
|
|
5431
|
+
fontFamily: "'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
5432
|
+
fontVariantNumeric: "tabular-nums",
|
|
5433
|
+
flexShrink: 0
|
|
5434
|
+
},
|
|
5113
5435
|
bottomRow: {
|
|
5114
5436
|
display: "flex",
|
|
5115
5437
|
justifyContent: "space-between",
|
|
5116
5438
|
alignItems: "center",
|
|
5117
|
-
gap: SPACE.S2
|
|
5439
|
+
gap: SPACE.S2,
|
|
5440
|
+
marginTop: "2px"
|
|
5118
5441
|
},
|
|
5119
5442
|
preview: {
|
|
5120
5443
|
fontSize: FONT_SIZE.sm,
|
|
5121
|
-
color: COLOR.
|
|
5444
|
+
color: COLOR.neutral500,
|
|
5122
5445
|
overflow: "hidden",
|
|
5123
5446
|
textOverflow: "ellipsis",
|
|
5124
5447
|
whiteSpace: "nowrap",
|
|
5125
5448
|
flex: 1,
|
|
5126
5449
|
minWidth: 0
|
|
5127
5450
|
},
|
|
5451
|
+
previewSender: {
|
|
5452
|
+
color: COLOR.neutral700,
|
|
5453
|
+
fontWeight: FONT_WEIGHT.semibold
|
|
5454
|
+
},
|
|
5128
5455
|
previewUnread: {
|
|
5129
5456
|
color: COLOR.neutral900,
|
|
5130
5457
|
fontWeight: FONT_WEIGHT.medium
|
|
5131
5458
|
},
|
|
5132
5459
|
badge: {
|
|
5133
|
-
minWidth: "
|
|
5134
|
-
height: "
|
|
5135
|
-
padding:
|
|
5460
|
+
minWidth: "22px",
|
|
5461
|
+
height: "22px",
|
|
5462
|
+
padding: "0 9px",
|
|
5136
5463
|
fontSize: FONT_SIZE.xs,
|
|
5137
|
-
fontWeight: FONT_WEIGHT.
|
|
5464
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
5138
5465
|
color: COLOR.white,
|
|
5139
|
-
backgroundColor: COLOR.
|
|
5466
|
+
backgroundColor: COLOR.danger,
|
|
5140
5467
|
borderRadius: RADIUS.pill,
|
|
5141
5468
|
display: "flex",
|
|
5142
5469
|
alignItems: "center",
|
|
5143
5470
|
justifyContent: "center",
|
|
5471
|
+
fontVariantNumeric: "tabular-nums",
|
|
5144
5472
|
flexShrink: 0
|
|
5145
5473
|
}
|
|
5146
5474
|
};
|
|
5475
|
+
function SearchIcon({ size = 20, color = "currentColor" }) {
|
|
5476
|
+
return /* @__PURE__ */ jsxs(
|
|
5477
|
+
"svg",
|
|
5478
|
+
{
|
|
5479
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5480
|
+
width: size,
|
|
5481
|
+
height: size,
|
|
5482
|
+
viewBox: "0 0 24 24",
|
|
5483
|
+
fill: "none",
|
|
5484
|
+
stroke: color,
|
|
5485
|
+
strokeWidth: "2",
|
|
5486
|
+
strokeLinecap: "round",
|
|
5487
|
+
strokeLinejoin: "round",
|
|
5488
|
+
"aria-hidden": "true",
|
|
5489
|
+
children: [
|
|
5490
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
5491
|
+
/* @__PURE__ */ jsx("path", { d: "M20 20l-4-4" })
|
|
5492
|
+
]
|
|
5493
|
+
}
|
|
5494
|
+
);
|
|
5495
|
+
}
|
|
5147
5496
|
function ConversationList({
|
|
5148
5497
|
conversations,
|
|
5149
5498
|
selectedId,
|
|
5150
5499
|
isLoading,
|
|
5151
5500
|
error,
|
|
5152
5501
|
onSelect,
|
|
5153
|
-
title = "Conversations",
|
|
5154
5502
|
className
|
|
5155
5503
|
}) {
|
|
5156
5504
|
const [query, setQuery] = useState("");
|
|
5157
|
-
const [
|
|
5505
|
+
const [filter, setFilter] = useState("all");
|
|
5506
|
+
const [searchFocused, setSearchFocused] = useState(false);
|
|
5507
|
+
const unreadCount = useMemo(
|
|
5508
|
+
() => conversations.filter((c) => c.unreadCount > 0).length,
|
|
5509
|
+
[conversations]
|
|
5510
|
+
);
|
|
5511
|
+
const autoDefaultedRef = useRef(false);
|
|
5512
|
+
useEffect(() => {
|
|
5513
|
+
if (autoDefaultedRef.current) return;
|
|
5514
|
+
if (conversations.length === 0) return;
|
|
5515
|
+
autoDefaultedRef.current = true;
|
|
5516
|
+
if (unreadCount > 0) setFilter("unread");
|
|
5517
|
+
}, [conversations.length, unreadCount]);
|
|
5158
5518
|
const filtered = useMemo(() => {
|
|
5159
5519
|
let result = conversations;
|
|
5160
|
-
if (
|
|
5520
|
+
if (filter === "unread") {
|
|
5161
5521
|
result = result.filter((c) => c.unreadCount > 0);
|
|
5162
5522
|
}
|
|
5163
5523
|
const q = query.trim().toLowerCase();
|
|
5164
5524
|
if (q) {
|
|
5165
5525
|
result = result.filter((c) => {
|
|
5166
|
-
const patient = c.patientSnapshot?.patientName?.toLowerCase() || "";
|
|
5167
5526
|
const name = c.name.toLowerCase();
|
|
5168
|
-
|
|
5527
|
+
const patient = c.patientSnapshot?.patientName?.toLowerCase() || "";
|
|
5528
|
+
const studyType = c.patientSnapshot?.studyType?.toLowerCase() || "";
|
|
5529
|
+
const patientId = c.patientSnapshot?.patientId?.toLowerCase() || "";
|
|
5530
|
+
return name.includes(q) || patient.includes(q) || studyType.includes(q) || patientId.includes(q);
|
|
5169
5531
|
});
|
|
5170
5532
|
}
|
|
5171
5533
|
return result;
|
|
5172
|
-
}, [conversations, query,
|
|
5173
|
-
const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
|
|
5534
|
+
}, [conversations, query, filter]);
|
|
5174
5535
|
return /* @__PURE__ */ jsxs("div", { className, style: styles16.container, children: [
|
|
5175
|
-
/* @__PURE__ */ jsxs("div", { style: styles16.
|
|
5176
|
-
/* @__PURE__ */
|
|
5177
|
-
|
|
5178
|
-
totalUnread > 0 && /* @__PURE__ */ jsx("span", { style: styles16.totalBadge, children: totalUnread })
|
|
5179
|
-
] }),
|
|
5180
|
-
/* @__PURE__ */ jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsx(
|
|
5181
|
-
"input",
|
|
5536
|
+
/* @__PURE__ */ jsxs("div", { style: styles16.tabs, children: [
|
|
5537
|
+
/* @__PURE__ */ jsx(
|
|
5538
|
+
TabButton,
|
|
5182
5539
|
{
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
style: styles16.searchInput
|
|
5540
|
+
label: "Unread",
|
|
5541
|
+
count: unreadCount,
|
|
5542
|
+
isActive: filter === "unread",
|
|
5543
|
+
onClick: () => setFilter("unread")
|
|
5188
5544
|
}
|
|
5189
|
-
)
|
|
5190
|
-
/* @__PURE__ */
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
type: "button",
|
|
5200
|
-
children: "All"
|
|
5201
|
-
}
|
|
5202
|
-
),
|
|
5203
|
-
/* @__PURE__ */ jsxs(
|
|
5204
|
-
"button",
|
|
5205
|
-
{
|
|
5206
|
-
onClick: () => setShowUnreadOnly(true),
|
|
5207
|
-
style: {
|
|
5208
|
-
...styles16.filterButton,
|
|
5209
|
-
...showUnreadOnly ? styles16.filterButtonActive : {}
|
|
5210
|
-
},
|
|
5211
|
-
type: "button",
|
|
5212
|
-
children: [
|
|
5213
|
-
"Unread ",
|
|
5214
|
-
totalUnread > 0 && `(${totalUnread})`
|
|
5215
|
-
]
|
|
5216
|
-
}
|
|
5217
|
-
)
|
|
5218
|
-
] })
|
|
5545
|
+
),
|
|
5546
|
+
/* @__PURE__ */ jsx(
|
|
5547
|
+
TabButton,
|
|
5548
|
+
{
|
|
5549
|
+
label: "All",
|
|
5550
|
+
count: conversations.length,
|
|
5551
|
+
isActive: filter === "all",
|
|
5552
|
+
onClick: () => setFilter("all")
|
|
5553
|
+
}
|
|
5554
|
+
)
|
|
5219
5555
|
] }),
|
|
5556
|
+
/* @__PURE__ */ jsxs(
|
|
5557
|
+
"div",
|
|
5558
|
+
{
|
|
5559
|
+
style: {
|
|
5560
|
+
...styles16.search,
|
|
5561
|
+
...searchFocused ? styles16.searchFocused : {}
|
|
5562
|
+
},
|
|
5563
|
+
children: [
|
|
5564
|
+
/* @__PURE__ */ jsx("span", { style: styles16.searchIcon, "aria-hidden": "true", children: /* @__PURE__ */ jsx(SearchIcon, { size: 20, color: COLOR.neutral500 }) }),
|
|
5565
|
+
/* @__PURE__ */ jsx(
|
|
5566
|
+
"input",
|
|
5567
|
+
{
|
|
5568
|
+
type: "text",
|
|
5569
|
+
value: query,
|
|
5570
|
+
onChange: (e) => setQuery(e.target.value),
|
|
5571
|
+
onFocus: () => setSearchFocused(true),
|
|
5572
|
+
onBlur: () => setSearchFocused(false),
|
|
5573
|
+
placeholder: "Search by patient name or MRN",
|
|
5574
|
+
"aria-label": "Search conversations",
|
|
5575
|
+
style: styles16.searchInput
|
|
5576
|
+
}
|
|
5577
|
+
)
|
|
5578
|
+
]
|
|
5579
|
+
}
|
|
5580
|
+
),
|
|
5220
5581
|
/* @__PURE__ */ jsxs("div", { style: styles16.list, children: [
|
|
5221
|
-
isLoading && /* @__PURE__ */
|
|
5222
|
-
|
|
5223
|
-
|
|
5582
|
+
isLoading && /* @__PURE__ */ jsxs("div", { style: styles16.loading, children: [
|
|
5583
|
+
/* @__PURE__ */ jsx(Spinner, { size: 16 }),
|
|
5584
|
+
/* @__PURE__ */ jsx("span", { children: "Loading conversations\u2026" })
|
|
5585
|
+
] }),
|
|
5586
|
+
error && !isLoading && /* @__PURE__ */ jsx("div", { style: styles16.errorState, children: error }),
|
|
5587
|
+
!isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsx(EmptyState, { filter, hasQuery: query.trim().length > 0 }),
|
|
5224
5588
|
filtered.map((item) => /* @__PURE__ */ jsx(
|
|
5225
5589
|
ConversationListItem,
|
|
5226
5590
|
{
|
|
@@ -5233,95 +5597,178 @@ function ConversationList({
|
|
|
5233
5597
|
] })
|
|
5234
5598
|
] });
|
|
5235
5599
|
}
|
|
5600
|
+
function TabButton({
|
|
5601
|
+
label,
|
|
5602
|
+
count,
|
|
5603
|
+
isActive,
|
|
5604
|
+
onClick
|
|
5605
|
+
}) {
|
|
5606
|
+
return /* @__PURE__ */ jsxs(
|
|
5607
|
+
"button",
|
|
5608
|
+
{
|
|
5609
|
+
type: "button",
|
|
5610
|
+
onClick,
|
|
5611
|
+
style: {
|
|
5612
|
+
...styles16.tab,
|
|
5613
|
+
...isActive ? styles16.tabActive : {}
|
|
5614
|
+
},
|
|
5615
|
+
children: [
|
|
5616
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
5617
|
+
/* @__PURE__ */ jsx(
|
|
5618
|
+
"span",
|
|
5619
|
+
{
|
|
5620
|
+
style: {
|
|
5621
|
+
...styles16.tabCount,
|
|
5622
|
+
...isActive ? styles16.tabCountActive : {}
|
|
5623
|
+
},
|
|
5624
|
+
children: count
|
|
5625
|
+
}
|
|
5626
|
+
)
|
|
5627
|
+
]
|
|
5628
|
+
}
|
|
5629
|
+
);
|
|
5630
|
+
}
|
|
5631
|
+
function EmptyState({ filter, hasQuery }) {
|
|
5632
|
+
let title = "No conversations yet";
|
|
5633
|
+
let subtitle = "New chats will show up here as cases come in.";
|
|
5634
|
+
if (filter === "unread") {
|
|
5635
|
+
title = "No unread messages";
|
|
5636
|
+
subtitle = "You're all caught up.";
|
|
5637
|
+
} else if (hasQuery) {
|
|
5638
|
+
title = "No conversations match";
|
|
5639
|
+
subtitle = "Try a different search.";
|
|
5640
|
+
}
|
|
5641
|
+
return /* @__PURE__ */ jsxs("div", { style: styles16.empty, children: [
|
|
5642
|
+
/* @__PURE__ */ jsx(ChatIllustration, { size: 88 }),
|
|
5643
|
+
/* @__PURE__ */ jsx("p", { style: styles16.emptyTitle, children: title }),
|
|
5644
|
+
/* @__PURE__ */ jsx("p", { style: styles16.emptySubtitle, children: subtitle })
|
|
5645
|
+
] });
|
|
5646
|
+
}
|
|
5236
5647
|
var styles16 = {
|
|
5237
5648
|
container: {
|
|
5238
5649
|
display: "flex",
|
|
5239
5650
|
flexDirection: "column",
|
|
5240
5651
|
height: "100%",
|
|
5241
|
-
backgroundColor: COLOR.white
|
|
5242
|
-
borderRight: `1px solid ${COLOR.neutral200}`
|
|
5652
|
+
backgroundColor: COLOR.white
|
|
5243
5653
|
},
|
|
5244
|
-
header
|
|
5245
|
-
|
|
5654
|
+
// Tabs sit at the top of the panel now (header section removed).
|
|
5655
|
+
// A bit more top padding so they don't crowd the top edge.
|
|
5656
|
+
tabs: {
|
|
5657
|
+
display: "flex",
|
|
5658
|
+
gap: SPACE.S2,
|
|
5659
|
+
padding: `${SPACE.S5} ${SPACE.S5} ${SPACE.S2}`,
|
|
5246
5660
|
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
5247
|
-
backgroundColor: COLOR.neutral50,
|
|
5248
5661
|
flexShrink: 0
|
|
5249
5662
|
},
|
|
5250
|
-
|
|
5251
|
-
display: "flex",
|
|
5663
|
+
tab: {
|
|
5664
|
+
display: "inline-flex",
|
|
5252
5665
|
alignItems: "center",
|
|
5253
5666
|
gap: SPACE.S2,
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5667
|
+
padding: `${SPACE.S2} ${SPACE.S4}`,
|
|
5668
|
+
backgroundColor: "transparent",
|
|
5669
|
+
border: "none",
|
|
5670
|
+
borderRadius: RADIUS.lg,
|
|
5671
|
+
cursor: "pointer",
|
|
5672
|
+
color: COLOR.neutral500,
|
|
5673
|
+
fontFamily: "inherit",
|
|
5674
|
+
fontSize: FONT_SIZE.sm,
|
|
5259
5675
|
fontWeight: FONT_WEIGHT.semibold,
|
|
5260
|
-
|
|
5676
|
+
transition: "background-color 120ms ease, color 120ms ease"
|
|
5261
5677
|
},
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5678
|
+
tabActive: {
|
|
5679
|
+
backgroundColor: COLOR.primaryBg,
|
|
5680
|
+
color: COLOR.primary
|
|
5681
|
+
},
|
|
5682
|
+
tabCount: {
|
|
5266
5683
|
fontSize: FONT_SIZE.xs,
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
backgroundColor: COLOR.primary,
|
|
5684
|
+
fontVariantNumeric: "tabular-nums",
|
|
5685
|
+
padding: "1px 8px",
|
|
5270
5686
|
borderRadius: RADIUS.pill,
|
|
5687
|
+
backgroundColor: COLOR.neutral200,
|
|
5688
|
+
color: COLOR.neutral500,
|
|
5689
|
+
fontWeight: FONT_WEIGHT.semibold
|
|
5690
|
+
},
|
|
5691
|
+
tabCountActive: {
|
|
5692
|
+
backgroundColor: COLOR.primary,
|
|
5693
|
+
color: COLOR.white
|
|
5694
|
+
},
|
|
5695
|
+
search: {
|
|
5271
5696
|
display: "flex",
|
|
5272
5697
|
alignItems: "center",
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5698
|
+
gap: SPACE.S2,
|
|
5699
|
+
margin: `14px ${SPACE.S5} ${SPACE.S3}`,
|
|
5700
|
+
padding: `${SPACE.S3} 14px`,
|
|
5701
|
+
backgroundColor: COLOR.neutral100,
|
|
5702
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
5703
|
+
borderRadius: "14px",
|
|
5704
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease"
|
|
5277
5705
|
},
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
border: `1px solid ${COLOR.neutral200}`,
|
|
5283
|
-
borderRadius: RADIUS.md,
|
|
5284
|
-
outline: "none",
|
|
5285
|
-
fontFamily: "inherit"
|
|
5706
|
+
searchFocused: {
|
|
5707
|
+
backgroundColor: COLOR.white,
|
|
5708
|
+
borderColor: COLOR.primary,
|
|
5709
|
+
boxShadow: `0 0 0 3px ${COLOR.primaryBg}`
|
|
5286
5710
|
},
|
|
5287
|
-
|
|
5711
|
+
searchIcon: {
|
|
5288
5712
|
display: "flex",
|
|
5289
|
-
|
|
5713
|
+
alignItems: "center",
|
|
5714
|
+
justifyContent: "center",
|
|
5715
|
+
flexShrink: 0
|
|
5290
5716
|
},
|
|
5291
|
-
|
|
5717
|
+
searchInput: {
|
|
5292
5718
|
flex: 1,
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
},
|
|
5301
|
-
filterButtonActive: {
|
|
5302
|
-
color: COLOR.white,
|
|
5303
|
-
backgroundColor: COLOR.primary,
|
|
5304
|
-
borderColor: COLOR.primary,
|
|
5305
|
-
fontWeight: FONT_WEIGHT.medium
|
|
5719
|
+
minWidth: 0,
|
|
5720
|
+
border: "none",
|
|
5721
|
+
background: "transparent",
|
|
5722
|
+
outline: "none",
|
|
5723
|
+
fontFamily: "inherit",
|
|
5724
|
+
fontSize: FONT_SIZE.md,
|
|
5725
|
+
color: COLOR.neutral900
|
|
5306
5726
|
},
|
|
5307
5727
|
list: {
|
|
5308
5728
|
flex: 1,
|
|
5309
|
-
overflowY: "auto"
|
|
5729
|
+
overflowY: "auto",
|
|
5730
|
+
padding: "4px 0 12px"
|
|
5310
5731
|
},
|
|
5311
|
-
|
|
5312
|
-
|
|
5732
|
+
loading: {
|
|
5733
|
+
display: "flex",
|
|
5734
|
+
alignItems: "center",
|
|
5735
|
+
justifyContent: "center",
|
|
5736
|
+
gap: SPACE.S2,
|
|
5737
|
+
padding: `44px ${SPACE.S5}`,
|
|
5313
5738
|
fontSize: FONT_SIZE.sm,
|
|
5314
|
-
color: COLOR.neutral500
|
|
5315
|
-
textAlign: "center"
|
|
5739
|
+
color: COLOR.neutral500
|
|
5316
5740
|
},
|
|
5317
5741
|
errorState: {
|
|
5318
5742
|
padding: SPACE.S4,
|
|
5743
|
+
margin: SPACE.S3,
|
|
5319
5744
|
fontSize: FONT_SIZE.sm,
|
|
5320
5745
|
color: COLOR.danger,
|
|
5321
5746
|
backgroundColor: COLOR.dangerBg,
|
|
5322
|
-
|
|
5747
|
+
border: `1px solid ${COLOR.dangerBorder}`,
|
|
5323
5748
|
borderRadius: RADIUS.md,
|
|
5324
5749
|
textAlign: "center"
|
|
5750
|
+
},
|
|
5751
|
+
empty: {
|
|
5752
|
+
display: "flex",
|
|
5753
|
+
flexDirection: "column",
|
|
5754
|
+
alignItems: "center",
|
|
5755
|
+
justifyContent: "center",
|
|
5756
|
+
padding: "44px 24px",
|
|
5757
|
+
textAlign: "center",
|
|
5758
|
+
color: COLOR.neutral500
|
|
5759
|
+
},
|
|
5760
|
+
emptyTitle: {
|
|
5761
|
+
margin: "12px 0 4px",
|
|
5762
|
+
fontSize: FONT_SIZE.md,
|
|
5763
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
5764
|
+
color: COLOR.neutral700
|
|
5765
|
+
},
|
|
5766
|
+
emptySubtitle: {
|
|
5767
|
+
margin: 0,
|
|
5768
|
+
fontSize: FONT_SIZE.sm,
|
|
5769
|
+
color: COLOR.neutral500,
|
|
5770
|
+
maxWidth: "280px",
|
|
5771
|
+
lineHeight: LINE_HEIGHT.normal
|
|
5325
5772
|
}
|
|
5326
5773
|
};
|
|
5327
5774
|
ensureGlobalStyles();
|
|
@@ -5329,7 +5776,6 @@ var COMPACT_BREAKPOINT = 720;
|
|
|
5329
5776
|
function CollabInbox({
|
|
5330
5777
|
initialConversationId,
|
|
5331
5778
|
onSelectConversation,
|
|
5332
|
-
title,
|
|
5333
5779
|
className,
|
|
5334
5780
|
style
|
|
5335
5781
|
}) {
|
|
@@ -5366,8 +5812,7 @@ function CollabInbox({
|
|
|
5366
5812
|
selectedId,
|
|
5367
5813
|
isLoading,
|
|
5368
5814
|
error,
|
|
5369
|
-
onSelect: handleSelect
|
|
5370
|
-
title
|
|
5815
|
+
onSelect: handleSelect
|
|
5371
5816
|
}
|
|
5372
5817
|
) }),
|
|
5373
5818
|
showDetail && /* @__PURE__ */ jsx("div", { style: isCompact ? styles17.mainCompact : styles17.main, children: selected ? /* @__PURE__ */ jsx(
|
|
@@ -5380,7 +5825,7 @@ function CollabInbox({
|
|
|
5380
5825
|
onBack: isCompact ? () => setSelectedId(null) : void 0
|
|
5381
5826
|
},
|
|
5382
5827
|
selected.id
|
|
5383
|
-
) : /* @__PURE__ */ jsx(
|
|
5828
|
+
) : /* @__PURE__ */ jsx(EmptyState2, { hasAny: conversations.length > 0 }) })
|
|
5384
5829
|
]
|
|
5385
5830
|
}
|
|
5386
5831
|
);
|
|
@@ -5414,7 +5859,7 @@ function parseChannelName(name, orderId) {
|
|
|
5414
5859
|
orderId
|
|
5415
5860
|
};
|
|
5416
5861
|
}
|
|
5417
|
-
function
|
|
5862
|
+
function EmptyState2({ hasAny }) {
|
|
5418
5863
|
return /* @__PURE__ */ jsxs("div", { style: styles17.empty, children: [
|
|
5419
5864
|
/* @__PURE__ */ jsx("div", { style: styles17.emptyIcon, children: "\u{1F4AC}" }),
|
|
5420
5865
|
/* @__PURE__ */ jsx("h3", { style: styles17.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
|
|
@@ -5793,6 +6238,6 @@ function usePinnedMessages({
|
|
|
5793
6238
|
};
|
|
5794
6239
|
}
|
|
5795
6240
|
|
|
5796
|
-
export { AUDIO_MIME_TYPE, ChannelSettings, CollabInbox, CollabInline, CollabPanel, CollabPopup, CollabProvider, CollabSocket, ConversationList, ConversationListItem, DEEP_LINK_PREFIX, EVENTS, MAX_FILE_SIZE, MAX_PINNED_MESSAGES, MESSAGES_PAGE_SIZE, MESSAGE_TYPES, MessageActionsMenu, MessageBubble, MessageInput, MessageList, ParticipantsList, PatientHeader, PinnedMessagesBar, ReplyPreview, ReplyQuoteBlock, SUPPORTED_IMAGE_TYPES, SeenByIndicator, TYPING_DEBOUNCE_MS, useAudioRecorder, useChannelSettings, useCollab, useConversation, useConversationList, useDeepLinks, useInlineCollab, useMessages, usePinnedMessages, useUnreadCount };
|
|
6241
|
+
export { AUDIO_MIME_TYPE, ChannelSettings, CollabInbox, CollabInline, CollabPanel, CollabPopup, CollabProvider, CollabSocket, ConversationList, ConversationListItem, DEEP_LINK_PREFIX, EVENTS, MAX_FILE_SIZE, MAX_PINNED_MESSAGES, MESSAGES_PAGE_SIZE, MESSAGE_TYPES, MessageActionsMenu, MessageBubble, MessageInput, MessageList, ParticipantsList, PatientHeader, PinnedMessagesBar, ReplyPreview, ReplyQuoteBlock, SUPPORTED_IMAGE_TYPES, SeenByIndicator, THEME_DEFAULTS, THEME_VAR, TYPING_DEBOUNCE_MS, applyThemeOverrides, useAudioRecorder, useChannelSettings, useCollab, useConversation, useConversationList, useDeepLinks, useInlineCollab, useMessages, usePinnedMessages, useUnreadCount };
|
|
5797
6242
|
//# sourceMappingURL=index.mjs.map
|
|
5798
6243
|
//# sourceMappingURL=index.mjs.map
|