@natoe/colab 0.1.11 → 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 +140 -14
- package/dist/index.d.ts +140 -14
- package/dist/index.js +1086 -616
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1085 -618
- 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,
|
|
@@ -569,7 +740,11 @@ function buildChannelName(patientData) {
|
|
|
569
740
|
const patientPart = patientData.patientName?.trim() || "Unknown";
|
|
570
741
|
const labPart = patientData.labName?.trim()?.slice(0, 24) || "";
|
|
571
742
|
const last4 = (patientData.displayOrderId ?? "").trim().slice(-4) || "0000";
|
|
572
|
-
return `${patientPart} - ${labPart} - ${last4}`;
|
|
743
|
+
return labPart ? `${patientPart} - ${labPart} - ${last4}` : `${patientPart} - ${last4}`;
|
|
744
|
+
}
|
|
745
|
+
function cleanChannelName(name) {
|
|
746
|
+
if (!name) return "";
|
|
747
|
+
return name.replace(/\s+-\s+-\s+/g, " - ").trim();
|
|
573
748
|
}
|
|
574
749
|
|
|
575
750
|
// src/hooks/useConversation.ts
|
|
@@ -604,8 +779,11 @@ function useConversation({
|
|
|
604
779
|
const ensureConversationInFlight = useRef(null);
|
|
605
780
|
const markedReadIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
606
781
|
const buildName = useCallback(
|
|
607
|
-
() =>
|
|
608
|
-
|
|
782
|
+
() => {
|
|
783
|
+
const labName = patientData.labName ?? (config.userRole === "lab" ? config.userName : void 0);
|
|
784
|
+
return buildChannelName({ ...patientData, labName });
|
|
785
|
+
},
|
|
786
|
+
[patientData, config.userRole, config.userName]
|
|
609
787
|
);
|
|
610
788
|
const joinChannel = useCallback(
|
|
611
789
|
(conv) => {
|
|
@@ -718,26 +896,22 @@ function useConversation({
|
|
|
718
896
|
setConversation(existingConv);
|
|
719
897
|
setParticipants(preview.participants);
|
|
720
898
|
joinChannel(existingConv);
|
|
721
|
-
setMessages(preview.lastMessages);
|
|
722
|
-
setHasMore(preview.messageCount > preview.lastMessages.length);
|
|
723
|
-
setPinnedMessages(preview.lastMessages.filter((m) => m.isPinned));
|
|
724
|
-
setIsLoading(false);
|
|
725
899
|
if (loadHistory) {
|
|
726
900
|
fetchMessages(preview.conversationId).then((history) => {
|
|
727
901
|
if (cancelled) return;
|
|
728
|
-
setMessages(
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
});
|
|
733
|
-
setHasMore(history.length > 0);
|
|
734
|
-
setPinnedMessages((prev) => {
|
|
735
|
-
const fromHistory = history.filter((m) => m.isPinned);
|
|
736
|
-
const seen = new Set(prev.map((m) => m.id));
|
|
737
|
-
return [...fromHistory.filter((m) => !seen.has(m.id)), ...prev];
|
|
738
|
-
});
|
|
902
|
+
setMessages(history);
|
|
903
|
+
setHasMore(history.length >= MESSAGES_PAGE_SIZE);
|
|
904
|
+
setPinnedMessages(history.filter((m) => m.isPinned));
|
|
905
|
+
setIsLoading(false);
|
|
739
906
|
}).catch(() => {
|
|
907
|
+
if (cancelled) return;
|
|
908
|
+
setIsLoading(false);
|
|
740
909
|
});
|
|
910
|
+
} else {
|
|
911
|
+
setMessages([]);
|
|
912
|
+
setHasMore(false);
|
|
913
|
+
setPinnedMessages([]);
|
|
914
|
+
setIsLoading(false);
|
|
741
915
|
}
|
|
742
916
|
} catch (err) {
|
|
743
917
|
if (cancelled) return;
|
|
@@ -818,7 +992,7 @@ function useConversation({
|
|
|
818
992
|
const payload = {
|
|
819
993
|
body,
|
|
820
994
|
type: "text",
|
|
821
|
-
...replyTo ? {
|
|
995
|
+
...replyTo ? { reply_to_id: replyTo.id } : {}
|
|
822
996
|
};
|
|
823
997
|
const { conv, persistedByCreate } = await ensureConversation(payload);
|
|
824
998
|
setReplyTo(null);
|
|
@@ -871,7 +1045,7 @@ function useConversation({
|
|
|
871
1045
|
const payload = {
|
|
872
1046
|
body: target.body,
|
|
873
1047
|
type: "text",
|
|
874
|
-
...target.replyToId ? {
|
|
1048
|
+
...target.replyToId ? { reply_to_id: target.replyToId } : {}
|
|
875
1049
|
};
|
|
876
1050
|
try {
|
|
877
1051
|
await socket.sendMessage(conversation.id, payload);
|
|
@@ -1196,106 +1370,10 @@ function BackIcon({ size = 22, color = "currentColor" }) {
|
|
|
1196
1370
|
}
|
|
1197
1371
|
);
|
|
1198
1372
|
}
|
|
1199
|
-
|
|
1200
|
-
// src/core/theme.ts
|
|
1201
|
-
var FONT_SIZE = {
|
|
1202
|
-
xs: "12px",
|
|
1203
|
-
sm: "13px",
|
|
1204
|
-
md: "15px",
|
|
1205
|
-
lg: "17px",
|
|
1206
|
-
xxl: "28px"
|
|
1207
|
-
};
|
|
1208
|
-
var FONT_WEIGHT = {
|
|
1209
|
-
regular: 400,
|
|
1210
|
-
medium: 500,
|
|
1211
|
-
semibold: 600,
|
|
1212
|
-
bold: 700
|
|
1213
|
-
};
|
|
1214
|
-
var LINE_HEIGHT = {
|
|
1215
|
-
tight: 1.3,
|
|
1216
|
-
normal: 1.45};
|
|
1217
|
-
var SPACE = {
|
|
1218
|
-
S1: "4px",
|
|
1219
|
-
S2: "8px",
|
|
1220
|
-
S3: "12px",
|
|
1221
|
-
S4: "16px",
|
|
1222
|
-
S5: "20px",
|
|
1223
|
-
S6: "24px",
|
|
1224
|
-
S12: "48px"
|
|
1225
|
-
};
|
|
1226
|
-
var RADIUS = {
|
|
1227
|
-
sm: "4px",
|
|
1228
|
-
md: "8px",
|
|
1229
|
-
lg: "12px",
|
|
1230
|
-
pill: "9999px",
|
|
1231
|
-
full: "50%"
|
|
1232
|
-
};
|
|
1233
|
-
var COLOR = {
|
|
1234
|
-
// Brand
|
|
1235
|
-
primary: "#2563eb",
|
|
1236
|
-
/** Tinted surface for chips/cards on brand-coloured states. */
|
|
1237
|
-
primaryBg: "#dbeafe",
|
|
1238
|
-
primaryFg: "#1d4ed8",
|
|
1239
|
-
// Neutral grayscale — taken from Tailwind's zinc-leaning slate, the
|
|
1240
|
-
// existing dominant family in the package.
|
|
1241
|
-
white: "#ffffff",
|
|
1242
|
-
neutral50: "#f9fafb",
|
|
1243
|
-
neutral100: "#f3f4f6",
|
|
1244
|
-
neutral200: "#e5e7eb",
|
|
1245
|
-
neutral300: "#d1d5db",
|
|
1246
|
-
neutral400: "#9ca3af",
|
|
1247
|
-
neutral500: "#6b7280",
|
|
1248
|
-
neutral600: "#4b5563",
|
|
1249
|
-
neutral700: "#374151",
|
|
1250
|
-
neutral800: "#1f2937",
|
|
1251
|
-
neutral900: "#111827",
|
|
1252
|
-
// Slate (used by day dividers + dialog title bar)
|
|
1253
|
-
slate200: "#e2e8f0",
|
|
1254
|
-
slate700: "#334155",
|
|
1255
|
-
slate800: "#1e293b",
|
|
1256
|
-
// Semantic
|
|
1257
|
-
success: "#059669",
|
|
1258
|
-
warning: "#d97706",
|
|
1259
|
-
danger: "#dc2626",
|
|
1260
|
-
dangerBg: "#fef2f2",
|
|
1261
|
-
dangerBorder: "#fecaca",
|
|
1262
|
-
dangerFg: "#b91c1c"
|
|
1263
|
-
};
|
|
1264
|
-
var SIZE = {
|
|
1265
|
-
/** Default interactive height (text buttons, list rows). */
|
|
1266
|
-
control: "40px",
|
|
1267
|
-
/** Square icon-only buttons inside chrome (popup title, menu trigger). */
|
|
1268
|
-
controlIcon: "36px",
|
|
1269
|
-
/** Primary input controls (textarea send/attach). 44px = WCAG min. */
|
|
1270
|
-
controlPrimary: "44px",
|
|
1271
|
-
/** Avatar in the inbox row. */
|
|
1272
|
-
avatar: "40px",
|
|
1273
|
-
/** Unread dot. */
|
|
1274
|
-
dot: "10px"
|
|
1275
|
-
};
|
|
1276
|
-
var SHADOW = {
|
|
1277
|
-
/** Cards / floating popovers (message-actions menu). */
|
|
1278
|
-
popover: "0 6px 18px rgba(0, 0, 0, 0.12)",
|
|
1279
|
-
/** Dialog (CollabPopup). */
|
|
1280
|
-
dialog: "0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)",
|
|
1281
|
-
/** Subtle separator shadow (sticky day divider, toast). */
|
|
1282
|
-
subtle: "0 1px 2px rgba(0, 0, 0, 0.04)",
|
|
1283
|
-
toast: "0 4px 12px rgba(0, 0, 0, 0.18)"
|
|
1284
|
-
};
|
|
1285
|
-
var Z_INDEX = {
|
|
1286
|
-
/** Sticky day divider — above bubbles, below interactive popovers. */
|
|
1287
|
-
sticky: 1,
|
|
1288
|
-
/** Toasts inside a panel. */
|
|
1289
|
-
toast: 20,
|
|
1290
|
-
/** Floating CollabPopup dialog. */
|
|
1291
|
-
dialog: 9999,
|
|
1292
|
-
/** Portaled message-actions menu — must sit above the dialog. */
|
|
1293
|
-
menu: 1e4
|
|
1294
|
-
};
|
|
1295
1373
|
function resolveDisplayName(patientData, displayName) {
|
|
1296
1374
|
const localComplete = !!patientData.labName && !!patientData.displayOrderId;
|
|
1297
1375
|
if (localComplete) return buildChannelName(patientData);
|
|
1298
|
-
return displayName
|
|
1376
|
+
return cleanChannelName(displayName) || buildChannelName(patientData);
|
|
1299
1377
|
}
|
|
1300
1378
|
function PatientHeader({
|
|
1301
1379
|
patientData,
|
|
@@ -1308,15 +1386,28 @@ function PatientHeader({
|
|
|
1308
1386
|
}) {
|
|
1309
1387
|
const hasDicom = !!(patientData.studyId && patientData.storageId);
|
|
1310
1388
|
const meta = [];
|
|
1311
|
-
if (patientData.patientAge
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
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 });
|
|
1316
1402
|
}
|
|
1317
|
-
if (patientData.
|
|
1318
|
-
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
|
+
});
|
|
1319
1409
|
}
|
|
1410
|
+
const hasActions = hasDicom && onOpenDicom || onOpenSettings;
|
|
1320
1411
|
return /* @__PURE__ */ jsxs("div", { className, style: styles.container, children: [
|
|
1321
1412
|
!hideName && /* @__PURE__ */ jsxs("div", { style: styles.nameRow, children: [
|
|
1322
1413
|
onBack && /* @__PURE__ */ jsx(
|
|
@@ -1332,54 +1423,55 @@ function PatientHeader({
|
|
|
1332
1423
|
),
|
|
1333
1424
|
/* @__PURE__ */ jsx("span", { style: styles.nameText, children: resolveDisplayName(patientData, displayName) })
|
|
1334
1425
|
] }),
|
|
1335
|
-
|
|
1336
|
-
/* @__PURE__ */ jsxs("
|
|
1337
|
-
item.label,
|
|
1338
|
-
":
|
|
1339
|
-
] }),
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
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
|
-
] }) : 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
|
+
] })
|
|
1371
1458
|
] });
|
|
1372
1459
|
}
|
|
1373
1460
|
var styles = {
|
|
1374
1461
|
container: {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
backgroundColor: COLOR.
|
|
1462
|
+
display: "flex",
|
|
1463
|
+
flexDirection: "column",
|
|
1464
|
+
backgroundColor: COLOR.primaryBg,
|
|
1465
|
+
borderBottom: `1px solid ${COLOR.neutral200}`
|
|
1378
1466
|
},
|
|
1467
|
+
// Optional name row, only when `hideName` is false (compact-inbox path)
|
|
1379
1468
|
nameRow: {
|
|
1380
1469
|
display: "flex",
|
|
1381
1470
|
alignItems: "center",
|
|
1382
|
-
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
|
|
1383
1475
|
},
|
|
1384
1476
|
backButton: {
|
|
1385
1477
|
width: SIZE.controlIcon,
|
|
@@ -1396,65 +1488,90 @@ var styles = {
|
|
|
1396
1488
|
},
|
|
1397
1489
|
nameText: {
|
|
1398
1490
|
fontSize: FONT_SIZE.lg,
|
|
1399
|
-
fontWeight: FONT_WEIGHT.
|
|
1491
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1400
1492
|
color: COLOR.neutral900,
|
|
1401
1493
|
lineHeight: LINE_HEIGHT.tight,
|
|
1494
|
+
letterSpacing: "-0.01em",
|
|
1402
1495
|
minWidth: 0,
|
|
1403
1496
|
overflow: "hidden",
|
|
1404
1497
|
textOverflow: "ellipsis",
|
|
1405
1498
|
whiteSpace: "nowrap"
|
|
1406
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.
|
|
1407
1512
|
metaRow: {
|
|
1408
1513
|
display: "flex",
|
|
1409
1514
|
flexWrap: "wrap",
|
|
1410
|
-
columnGap: SPACE.
|
|
1411
|
-
rowGap: SPACE.
|
|
1412
|
-
|
|
1515
|
+
columnGap: SPACE.S5,
|
|
1516
|
+
rowGap: SPACE.S2,
|
|
1517
|
+
minWidth: 0
|
|
1413
1518
|
},
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1519
|
+
metaCol: {
|
|
1520
|
+
display: "flex",
|
|
1521
|
+
flexDirection: "column",
|
|
1522
|
+
gap: "2px",
|
|
1523
|
+
minWidth: 0
|
|
1418
1524
|
},
|
|
1419
1525
|
metaLabel: {
|
|
1526
|
+
fontSize: "11px",
|
|
1527
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1528
|
+
letterSpacing: "0.06em",
|
|
1529
|
+
textTransform: "uppercase",
|
|
1420
1530
|
color: COLOR.neutral500,
|
|
1421
|
-
|
|
1531
|
+
whiteSpace: "nowrap"
|
|
1422
1532
|
},
|
|
1423
1533
|
metaValue: {
|
|
1424
|
-
|
|
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"
|
|
1425
1541
|
},
|
|
1426
1542
|
actions: {
|
|
1427
1543
|
display: "flex",
|
|
1428
1544
|
gap: SPACE.S2,
|
|
1429
|
-
|
|
1545
|
+
flexShrink: 0
|
|
1430
1546
|
},
|
|
1431
1547
|
dicomButton: {
|
|
1432
1548
|
display: "inline-flex",
|
|
1433
1549
|
alignItems: "center",
|
|
1434
1550
|
gap: SPACE.S2,
|
|
1435
1551
|
minHeight: SIZE.control,
|
|
1436
|
-
padding: `${SPACE.S2}
|
|
1552
|
+
padding: `${SPACE.S2} 14px`,
|
|
1437
1553
|
fontSize: FONT_SIZE.sm,
|
|
1438
|
-
fontWeight: FONT_WEIGHT.
|
|
1439
|
-
color: COLOR.
|
|
1440
|
-
backgroundColor: COLOR.
|
|
1441
|
-
border:
|
|
1442
|
-
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,
|
|
1443
1559
|
cursor: "pointer"
|
|
1444
1560
|
},
|
|
1445
|
-
|
|
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,
|
|
1446
1566
|
display: "inline-flex",
|
|
1447
1567
|
alignItems: "center",
|
|
1448
|
-
|
|
1449
|
-
minHeight: SIZE.control,
|
|
1450
|
-
padding: `${SPACE.S2} ${SPACE.S4}`,
|
|
1451
|
-
fontSize: FONT_SIZE.sm,
|
|
1452
|
-
fontWeight: FONT_WEIGHT.medium,
|
|
1453
|
-
color: COLOR.neutral700,
|
|
1568
|
+
justifyContent: "center",
|
|
1454
1569
|
backgroundColor: COLOR.white,
|
|
1455
|
-
border: `1px solid ${COLOR.
|
|
1456
|
-
borderRadius: RADIUS.
|
|
1457
|
-
|
|
1570
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1571
|
+
borderRadius: RADIUS.lg,
|
|
1572
|
+
color: COLOR.neutral600,
|
|
1573
|
+
cursor: "pointer",
|
|
1574
|
+
flexShrink: 0
|
|
1458
1575
|
}
|
|
1459
1576
|
};
|
|
1460
1577
|
function ReplyQuoteBlock({
|
|
@@ -1463,10 +1580,10 @@ function ReplyQuoteBlock({
|
|
|
1463
1580
|
onClick,
|
|
1464
1581
|
className
|
|
1465
1582
|
}) {
|
|
1466
|
-
const baseBg = inOwnBubble ? "rgba(255,255,255,0.
|
|
1583
|
+
const baseBg = inOwnBubble ? "rgba(255,255,255,0.22)" : COLOR.white;
|
|
1467
1584
|
const barColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1468
1585
|
const nameColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1469
|
-
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.
|
|
1586
|
+
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.9)" : COLOR.neutral700;
|
|
1470
1587
|
const preview = renderSnapshotPreview(snapshot);
|
|
1471
1588
|
return /* @__PURE__ */ jsxs(
|
|
1472
1589
|
"div",
|
|
@@ -1838,43 +1955,50 @@ var styles4 = {
|
|
|
1838
1955
|
position: "relative",
|
|
1839
1956
|
display: "inline-block"
|
|
1840
1957
|
},
|
|
1958
|
+
// Pill-shaped trigger matching the prototype's `.nc-msg-act` style —
|
|
1959
|
+
// always visible (touch-friendly) rather than hover-only.
|
|
1841
1960
|
trigger: {
|
|
1842
|
-
|
|
1843
|
-
height: SIZE.controlIcon,
|
|
1844
|
-
display: "flex",
|
|
1961
|
+
display: "inline-flex",
|
|
1845
1962
|
alignItems: "center",
|
|
1846
1963
|
justifyContent: "center",
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1964
|
+
width: "32px",
|
|
1965
|
+
height: "32px",
|
|
1966
|
+
backgroundColor: COLOR.white,
|
|
1967
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1968
|
+
borderRadius: "999px",
|
|
1850
1969
|
cursor: "pointer",
|
|
1851
|
-
color: COLOR.neutral600
|
|
1970
|
+
color: COLOR.neutral600,
|
|
1971
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
1852
1972
|
},
|
|
1853
1973
|
menu: {
|
|
1854
1974
|
position: "fixed",
|
|
1855
|
-
minWidth: "
|
|
1975
|
+
minWidth: "200px",
|
|
1856
1976
|
backgroundColor: COLOR.white,
|
|
1857
|
-
border: `1px solid ${COLOR.
|
|
1858
|
-
borderRadius: RADIUS.
|
|
1977
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
1978
|
+
borderRadius: RADIUS.lg,
|
|
1859
1979
|
boxShadow: SHADOW.popover,
|
|
1860
|
-
padding:
|
|
1980
|
+
padding: "6px",
|
|
1981
|
+
display: "flex",
|
|
1982
|
+
flexDirection: "column",
|
|
1983
|
+
gap: "2px",
|
|
1861
1984
|
// Above the floating popup (z-index dialog) but below any future modal.
|
|
1862
1985
|
zIndex: Z_INDEX.menu
|
|
1863
1986
|
},
|
|
1864
1987
|
item: {
|
|
1865
1988
|
display: "flex",
|
|
1866
1989
|
alignItems: "center",
|
|
1867
|
-
gap: SPACE.
|
|
1990
|
+
gap: SPACE.S2,
|
|
1868
1991
|
width: "100%",
|
|
1869
1992
|
minHeight: SIZE.control,
|
|
1870
|
-
padding:
|
|
1993
|
+
padding: `10px ${SPACE.S3}`,
|
|
1871
1994
|
fontSize: FONT_SIZE.sm,
|
|
1872
|
-
color: COLOR.
|
|
1995
|
+
color: COLOR.neutral700,
|
|
1873
1996
|
backgroundColor: "transparent",
|
|
1874
1997
|
border: "none",
|
|
1875
|
-
borderRadius: RADIUS.
|
|
1998
|
+
borderRadius: RADIUS.md,
|
|
1876
1999
|
cursor: "pointer",
|
|
1877
|
-
textAlign: "left"
|
|
2000
|
+
textAlign: "left",
|
|
2001
|
+
fontFamily: "inherit"
|
|
1878
2002
|
},
|
|
1879
2003
|
itemDisabled: {
|
|
1880
2004
|
color: COLOR.neutral400,
|
|
@@ -1988,71 +2112,116 @@ function MessageBubble({
|
|
|
1988
2112
|
},
|
|
1989
2113
|
children: [
|
|
1990
2114
|
isOwn && actionsSlot,
|
|
1991
|
-
/* @__PURE__ */
|
|
1992
|
-
"div",
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
message.type === "image" && /* @__PURE__ */ jsx(ImageContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2018
|
-
message.type === "file" && /* @__PURE__ */ jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2019
|
-
message.type === "deep_link" && /* @__PURE__ */ jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
2020
|
-
/* @__PURE__ */ jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
2021
|
-
isOwn && message.status === "sending" && /* @__PURE__ */ jsxs("div", { style: styles5.statusRow, children: [
|
|
2022
|
-
/* @__PURE__ */ jsx(Spinner, { size: 12, color: "rgba(255,255,255,0.85)" }),
|
|
2023
|
-
/* @__PURE__ */ jsx("span", { style: styles5.statusText, children: "Sending\u2026" })
|
|
2024
|
-
] }),
|
|
2025
|
-
isOwn && message.status === "failed" && /* @__PURE__ */ jsxs("div", { style: styles5.statusRow, children: [
|
|
2026
|
-
/* @__PURE__ */ jsx(AlertIcon, { size: 12, color: "#fecaca" }),
|
|
2027
|
-
/* @__PURE__ */ jsx("span", { style: styles5.statusText, children: "Not sent" }),
|
|
2028
|
-
onRetry && /* @__PURE__ */ jsx(
|
|
2029
|
-
"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",
|
|
2030
2141
|
{
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
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
|
+
]
|
|
2036
2150
|
}
|
|
2037
|
-
)
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
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
|
+
] }),
|
|
2051
2199
|
!isOwn && actionsSlot
|
|
2052
2200
|
]
|
|
2053
2201
|
}
|
|
2054
2202
|
);
|
|
2055
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
|
+
}
|
|
2056
2225
|
function TextContent({ body, onDeepLinkClick }) {
|
|
2057
2226
|
if (body.includes(DEEP_LINK_PREFIX)) {
|
|
2058
2227
|
const parts = body.split(new RegExp(`(${escapeRegex2(DEEP_LINK_PREFIX)}[\\w/.-]+)`, "g"));
|
|
@@ -2114,19 +2283,13 @@ function DeepLinkContent({
|
|
|
2114
2283
|
);
|
|
2115
2284
|
}
|
|
2116
2285
|
function SystemBubble({ message }) {
|
|
2117
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsx("div", { style: styles5.systemWrapper, children: /* @__PURE__ */ jsxs("span", { style: styles5.systemPill, children: [
|
|
2118
2287
|
/* @__PURE__ */ jsx("span", { children: message.body }),
|
|
2119
2288
|
/* @__PURE__ */ jsx("span", { style: styles5.systemTime, children: formatTime(message.insertedAt) })
|
|
2120
|
-
] });
|
|
2289
|
+
] }) });
|
|
2121
2290
|
}
|
|
2122
2291
|
function RoleBadge({ role }) {
|
|
2123
|
-
|
|
2124
|
-
radiologist: "#7c3aed",
|
|
2125
|
-
lab: "#2563eb",
|
|
2126
|
-
physician: "#059669",
|
|
2127
|
-
admin: "#dc2626"
|
|
2128
|
-
};
|
|
2129
|
-
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 });
|
|
2130
2293
|
}
|
|
2131
2294
|
function formatTime(iso) {
|
|
2132
2295
|
try {
|
|
@@ -2148,89 +2311,134 @@ var styles5 = {
|
|
|
2148
2311
|
display: "flex",
|
|
2149
2312
|
alignItems: "flex-end",
|
|
2150
2313
|
gap: SPACE.S1,
|
|
2151
|
-
marginBottom: SPACE.
|
|
2314
|
+
marginBottom: SPACE.S3,
|
|
2152
2315
|
paddingLeft: SPACE.S4,
|
|
2153
2316
|
paddingRight: SPACE.S4
|
|
2154
2317
|
},
|
|
2155
2318
|
bubbleWrapper: {
|
|
2156
2319
|
position: "relative",
|
|
2157
|
-
maxWidth: "
|
|
2320
|
+
maxWidth: "78%",
|
|
2321
|
+
display: "flex",
|
|
2322
|
+
flexDirection: "column",
|
|
2323
|
+
gap: "4px"
|
|
2158
2324
|
},
|
|
2159
2325
|
actionsSlot: {
|
|
2160
2326
|
flexShrink: 0,
|
|
2161
2327
|
alignSelf: "flex-end"
|
|
2162
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
|
+
},
|
|
2163
2357
|
bubble: {
|
|
2164
2358
|
padding: `${SPACE.S3} ${SPACE.S4}`,
|
|
2165
|
-
borderRadius:
|
|
2166
|
-
wordBreak: "break-word"
|
|
2359
|
+
borderRadius: "18px",
|
|
2360
|
+
wordBreak: "break-word",
|
|
2361
|
+
border: "1px solid transparent"
|
|
2167
2362
|
},
|
|
2168
2363
|
ownBubble: {
|
|
2169
2364
|
backgroundColor: COLOR.primary,
|
|
2170
2365
|
color: COLOR.white,
|
|
2171
|
-
|
|
2366
|
+
borderColor: COLOR.primary,
|
|
2367
|
+
borderBottomRightRadius: "6px"
|
|
2172
2368
|
},
|
|
2173
2369
|
otherBubble: {
|
|
2174
2370
|
backgroundColor: COLOR.neutral100,
|
|
2175
2371
|
color: COLOR.neutral900,
|
|
2176
|
-
|
|
2372
|
+
borderColor: COLOR.neutral200,
|
|
2373
|
+
borderBottomLeftRadius: "6px"
|
|
2177
2374
|
},
|
|
2178
2375
|
pinnedBadge: {
|
|
2179
2376
|
display: "inline-flex",
|
|
2180
2377
|
alignItems: "center",
|
|
2181
|
-
gap:
|
|
2182
|
-
fontSize:
|
|
2183
|
-
fontWeight: FONT_WEIGHT.
|
|
2184
|
-
marginBottom: SPACE.
|
|
2185
|
-
|
|
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"
|
|
2186
2386
|
},
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
gap: SPACE.S2,
|
|
2191
|
-
marginBottom: SPACE.S1
|
|
2387
|
+
pinnedBadgeOther: {
|
|
2388
|
+
color: "#b8680f",
|
|
2389
|
+
backgroundColor: "#fff7e0"
|
|
2192
2390
|
},
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
color: COLOR.neutral700
|
|
2391
|
+
pinnedBadgeOwn: {
|
|
2392
|
+
color: "#fff4d6",
|
|
2393
|
+
backgroundColor: "rgba(255, 255, 255, 0.2)"
|
|
2197
2394
|
},
|
|
2198
2395
|
roleBadge: {
|
|
2199
|
-
fontSize:
|
|
2200
|
-
fontWeight: FONT_WEIGHT.
|
|
2201
|
-
padding:
|
|
2202
|
-
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
|
|
2203
2404
|
},
|
|
2204
2405
|
textBody: {
|
|
2205
2406
|
margin: 0,
|
|
2206
2407
|
fontSize: FONT_SIZE.md,
|
|
2207
|
-
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
|
|
2208
2418
|
},
|
|
2209
2419
|
timestamp: {
|
|
2210
|
-
fontSize:
|
|
2420
|
+
fontSize: "11px",
|
|
2211
2421
|
color: "inherit",
|
|
2212
|
-
|
|
2213
|
-
marginTop: SPACE.S1,
|
|
2214
|
-
textAlign: "right"
|
|
2422
|
+
fontVariantNumeric: "tabular-nums"
|
|
2215
2423
|
},
|
|
2216
|
-
|
|
2217
|
-
display: "flex",
|
|
2424
|
+
footStatus: {
|
|
2425
|
+
display: "inline-flex",
|
|
2218
2426
|
alignItems: "center",
|
|
2219
|
-
gap:
|
|
2220
|
-
|
|
2221
|
-
fontSize: FONT_SIZE.xs,
|
|
2222
|
-
justifyContent: "flex-end",
|
|
2223
|
-
color: "rgba(255, 255, 255, 0.9)"
|
|
2427
|
+
gap: "4px",
|
|
2428
|
+
fontSize: "11px"
|
|
2224
2429
|
},
|
|
2225
|
-
|
|
2226
|
-
|
|
2430
|
+
footStatusFailed: {
|
|
2431
|
+
display: "inline-flex",
|
|
2432
|
+
alignItems: "center",
|
|
2433
|
+
gap: "4px",
|
|
2434
|
+
fontSize: "11px"
|
|
2227
2435
|
},
|
|
2228
2436
|
retryButton: {
|
|
2229
2437
|
background: "transparent",
|
|
2230
2438
|
border: "none",
|
|
2231
2439
|
color: COLOR.white,
|
|
2232
2440
|
fontWeight: FONT_WEIGHT.semibold,
|
|
2233
|
-
fontSize:
|
|
2441
|
+
fontSize: "11px",
|
|
2234
2442
|
textDecoration: "underline",
|
|
2235
2443
|
cursor: "pointer",
|
|
2236
2444
|
padding: `0 ${SPACE.S1}`
|
|
@@ -2293,18 +2501,25 @@ var styles5 = {
|
|
|
2293
2501
|
color: COLOR.neutral500,
|
|
2294
2502
|
fontFamily: "monospace"
|
|
2295
2503
|
},
|
|
2296
|
-
|
|
2504
|
+
systemWrapper: {
|
|
2297
2505
|
display: "flex",
|
|
2298
2506
|
justifyContent: "center",
|
|
2507
|
+
margin: `${SPACE.S2} 0`
|
|
2508
|
+
},
|
|
2509
|
+
systemPill: {
|
|
2510
|
+
display: "inline-flex",
|
|
2299
2511
|
alignItems: "center",
|
|
2300
2512
|
gap: SPACE.S2,
|
|
2301
|
-
padding:
|
|
2302
|
-
|
|
2513
|
+
padding: `5px ${SPACE.S3}`,
|
|
2514
|
+
backgroundColor: COLOR.neutral100,
|
|
2515
|
+
borderRadius: "999px",
|
|
2516
|
+
fontSize: FONT_SIZE.xs,
|
|
2303
2517
|
color: COLOR.neutral500
|
|
2304
2518
|
},
|
|
2305
2519
|
systemTime: {
|
|
2306
|
-
fontSize:
|
|
2307
|
-
color: COLOR.neutral400
|
|
2520
|
+
fontSize: "11px",
|
|
2521
|
+
color: COLOR.neutral400,
|
|
2522
|
+
fontVariantNumeric: "tabular-nums"
|
|
2308
2523
|
}
|
|
2309
2524
|
};
|
|
2310
2525
|
function ChatIllustration({ size = 96 }) {
|
|
@@ -2443,6 +2658,7 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2443
2658
|
const containerRef = useRef(null);
|
|
2444
2659
|
const bottomRef = useRef(null);
|
|
2445
2660
|
const prevMessageCount = useRef(messages.length);
|
|
2661
|
+
const hasInitiallyScrolledRef = useRef(false);
|
|
2446
2662
|
useImperativeHandle(
|
|
2447
2663
|
ref,
|
|
2448
2664
|
() => ({
|
|
@@ -2460,7 +2676,31 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2460
2676
|
}),
|
|
2461
2677
|
[]
|
|
2462
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]);
|
|
2463
2702
|
useEffect(() => {
|
|
2703
|
+
if (!hasInitiallyScrolledRef.current) return;
|
|
2464
2704
|
if (messages.length > prevMessageCount.current) {
|
|
2465
2705
|
const lastMessage = messages[messages.length - 1];
|
|
2466
2706
|
const isOwnMessage = lastMessage?.senderId === currentUserId;
|
|
@@ -2519,7 +2759,11 @@ var MessageList = forwardRef(function MessageList2({
|
|
|
2519
2759
|
const showDivider = !!currentBucket && currentBucket !== lastValidBucket;
|
|
2520
2760
|
if (currentBucket) lastValidBucket = currentBucket;
|
|
2521
2761
|
return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
2522
|
-
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
|
+
] }),
|
|
2523
2767
|
/* @__PURE__ */ jsx("div", { "data-message-id": message.id, "data-natoe-message-bubble": true, style: styles6.bubbleSlot, children: /* @__PURE__ */ jsx(
|
|
2524
2768
|
MessageBubble,
|
|
2525
2769
|
{
|
|
@@ -2618,23 +2862,32 @@ var styles6 = {
|
|
|
2618
2862
|
},
|
|
2619
2863
|
dayDivider: {
|
|
2620
2864
|
display: "flex",
|
|
2621
|
-
|
|
2622
|
-
|
|
2865
|
+
alignItems: "center",
|
|
2866
|
+
gap: SPACE.S3,
|
|
2867
|
+
margin: `${SPACE.S4} 0 ${SPACE.S3}`,
|
|
2623
2868
|
position: "sticky",
|
|
2624
2869
|
top: SPACE.S1,
|
|
2625
2870
|
zIndex: Z_INDEX.sticky,
|
|
2626
2871
|
pointerEvents: "none"
|
|
2627
2872
|
},
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
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
|
|
2638
2891
|
},
|
|
2639
2892
|
bubbleSlot: {
|
|
2640
2893
|
animation: "natoe-colab-message-in 180ms ease-out"
|
|
@@ -2888,11 +3141,11 @@ function MessageInput({
|
|
|
2888
3141
|
{
|
|
2889
3142
|
onClick: () => fileInputRef.current?.click(),
|
|
2890
3143
|
disabled: disabled || isSending,
|
|
2891
|
-
style: styles8.
|
|
3144
|
+
style: styles8.attachButton,
|
|
2892
3145
|
"aria-label": "Attach file",
|
|
2893
3146
|
title: "Attach file",
|
|
2894
3147
|
type: "button",
|
|
2895
|
-
children: /* @__PURE__ */ jsx(AttachIcon, { size: 22, color:
|
|
3148
|
+
children: /* @__PURE__ */ jsx(AttachIcon, { size: 22, color: COLOR.neutral700 })
|
|
2896
3149
|
}
|
|
2897
3150
|
),
|
|
2898
3151
|
/* @__PURE__ */ jsx(
|
|
@@ -2931,7 +3184,7 @@ function MessageInput({
|
|
|
2931
3184
|
style: styles8.textarea
|
|
2932
3185
|
}
|
|
2933
3186
|
),
|
|
2934
|
-
/* @__PURE__ */
|
|
3187
|
+
/* @__PURE__ */ jsxs(
|
|
2935
3188
|
"button",
|
|
2936
3189
|
{
|
|
2937
3190
|
onClick: handleSendText,
|
|
@@ -2940,10 +3193,13 @@ function MessageInput({
|
|
|
2940
3193
|
title: "Send message",
|
|
2941
3194
|
style: {
|
|
2942
3195
|
...styles8.sendButton,
|
|
2943
|
-
opacity: text.trim() ? 1 : 0.
|
|
3196
|
+
opacity: text.trim() ? 1 : 0.5
|
|
2944
3197
|
},
|
|
2945
3198
|
type: "button",
|
|
2946
|
-
children:
|
|
3199
|
+
children: [
|
|
3200
|
+
/* @__PURE__ */ jsx(SendIcon, { size: 20, color: COLOR.white }),
|
|
3201
|
+
/* @__PURE__ */ jsx("span", { style: styles8.sendLabel, children: "Send" })
|
|
3202
|
+
]
|
|
2947
3203
|
}
|
|
2948
3204
|
)
|
|
2949
3205
|
] })
|
|
@@ -3005,49 +3261,67 @@ var styles8 = {
|
|
|
3005
3261
|
inputBar: {
|
|
3006
3262
|
display: "flex",
|
|
3007
3263
|
alignItems: "flex-end",
|
|
3008
|
-
gap:
|
|
3009
|
-
padding: `${SPACE.S3} ${SPACE.
|
|
3010
|
-
},
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
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",
|
|
3014
3273
|
display: "flex",
|
|
3015
3274
|
alignItems: "center",
|
|
3016
3275
|
justifyContent: "center",
|
|
3017
|
-
backgroundColor:
|
|
3018
|
-
border:
|
|
3019
|
-
borderRadius:
|
|
3276
|
+
backgroundColor: COLOR.neutral100,
|
|
3277
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3278
|
+
borderRadius: "14px",
|
|
3020
3279
|
cursor: "pointer",
|
|
3021
|
-
flexShrink: 0
|
|
3280
|
+
flexShrink: 0,
|
|
3281
|
+
color: COLOR.neutral700,
|
|
3282
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
3022
3283
|
},
|
|
3023
3284
|
textarea: {
|
|
3024
3285
|
flex: 1,
|
|
3025
|
-
|
|
3286
|
+
minHeight: "48px",
|
|
3287
|
+
maxHeight: "140px",
|
|
3288
|
+
padding: "13px 16px",
|
|
3026
3289
|
fontSize: FONT_SIZE.md,
|
|
3027
3290
|
lineHeight: LINE_HEIGHT.normal,
|
|
3028
|
-
|
|
3029
|
-
|
|
3291
|
+
color: COLOR.neutral900,
|
|
3292
|
+
backgroundColor: COLOR.neutral100,
|
|
3293
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3294
|
+
borderRadius: "14px",
|
|
3030
3295
|
resize: "none",
|
|
3031
3296
|
outline: "none",
|
|
3032
3297
|
fontFamily: "inherit",
|
|
3033
|
-
|
|
3034
|
-
minHeight: SIZE.controlPrimary
|
|
3298
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease"
|
|
3035
3299
|
},
|
|
3300
|
+
// Pill-shaped send: icon + "Send" label. Always labelled (never icon-
|
|
3301
|
+
// only) so the affordance is obvious to first-time users.
|
|
3036
3302
|
sendButton: {
|
|
3037
|
-
|
|
3038
|
-
height: SIZE.controlPrimary,
|
|
3039
|
-
display: "flex",
|
|
3303
|
+
display: "inline-flex",
|
|
3040
3304
|
alignItems: "center",
|
|
3041
|
-
|
|
3305
|
+
gap: "6px",
|
|
3306
|
+
minWidth: "48px",
|
|
3307
|
+
height: "48px",
|
|
3308
|
+
padding: `0 ${SPACE.S4}`,
|
|
3042
3309
|
backgroundColor: COLOR.primary,
|
|
3043
3310
|
color: COLOR.white,
|
|
3044
3311
|
border: "none",
|
|
3045
|
-
borderRadius:
|
|
3312
|
+
borderRadius: "14px",
|
|
3046
3313
|
cursor: "pointer",
|
|
3047
|
-
flexShrink: 0
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
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
|
|
3322
|
+
}};
|
|
3323
|
+
function ParticipantsList({
|
|
3324
|
+
participants,
|
|
3051
3325
|
currentUserId,
|
|
3052
3326
|
isAdmin,
|
|
3053
3327
|
onRemoveUser,
|
|
@@ -3101,10 +3375,14 @@ function fallbackName(role) {
|
|
|
3101
3375
|
}
|
|
3102
3376
|
function RoleBadge2({ role }) {
|
|
3103
3377
|
const colors = {
|
|
3104
|
-
radiologist: { bg: "#
|
|
3378
|
+
radiologist: { bg: "#eef2ff", text: "#4f46e5" },
|
|
3379
|
+
// indigo
|
|
3105
3380
|
lab: { bg: "#eff6ff", text: "#2563eb" },
|
|
3106
|
-
|
|
3107
|
-
|
|
3381
|
+
// brand blue
|
|
3382
|
+
physician: { bg: "#e0f2fe", text: "#0284c7" },
|
|
3383
|
+
// sky
|
|
3384
|
+
admin: { bg: "#f1f5f9", text: "#64748b" }
|
|
3385
|
+
// slate
|
|
3108
3386
|
};
|
|
3109
3387
|
const color = colors[role];
|
|
3110
3388
|
return /* @__PURE__ */ jsx("span", { style: { ...styles9.roleBadge, backgroundColor: color.bg, color: color.text }, children: role });
|
|
@@ -3713,45 +3991,6 @@ var styles12 = {
|
|
|
3713
3991
|
letterSpacing: "0.4px"
|
|
3714
3992
|
}
|
|
3715
3993
|
};
|
|
3716
|
-
|
|
3717
|
-
// src/core/styles.ts
|
|
3718
|
-
var FONT_STACK = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
3719
|
-
var ROOT_CLASS = "natoe-colab-root";
|
|
3720
|
-
var GLOBAL_STYLE_ID = "natoe-colab-global-styles";
|
|
3721
|
-
var GLOBAL_CSS = `
|
|
3722
|
-
@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }
|
|
3723
|
-
|
|
3724
|
-
@keyframes natoe-colab-message-in {
|
|
3725
|
-
from { opacity: 0; transform: translateY(4px); }
|
|
3726
|
-
to { opacity: 1; transform: translateY(0); }
|
|
3727
|
-
}
|
|
3728
|
-
|
|
3729
|
-
/* High-contrast adjustments \u2014 older users on OS-level high-contrast mode
|
|
3730
|
-
get heavier borders and stronger text without losing the package look. */
|
|
3731
|
-
@media (prefers-contrast: more) {
|
|
3732
|
-
.${ROOT_CLASS} {
|
|
3733
|
-
color: #000000;
|
|
3734
|
-
}
|
|
3735
|
-
.${ROOT_CLASS} button {
|
|
3736
|
-
outline: 1px solid currentColor;
|
|
3737
|
-
}
|
|
3738
|
-
}
|
|
3739
|
-
|
|
3740
|
-
/* Honour reduced-motion preferences by killing entry animations. */
|
|
3741
|
-
@media (prefers-reduced-motion: reduce) {
|
|
3742
|
-
.${ROOT_CLASS} [data-natoe-message-bubble] {
|
|
3743
|
-
animation: none !important;
|
|
3744
|
-
}
|
|
3745
|
-
}
|
|
3746
|
-
`;
|
|
3747
|
-
function ensureGlobalStyles() {
|
|
3748
|
-
if (typeof document === "undefined") return;
|
|
3749
|
-
if (document.getElementById(GLOBAL_STYLE_ID)) return;
|
|
3750
|
-
const style = document.createElement("style");
|
|
3751
|
-
style.id = GLOBAL_STYLE_ID;
|
|
3752
|
-
style.textContent = GLOBAL_CSS;
|
|
3753
|
-
document.head.appendChild(style);
|
|
3754
|
-
}
|
|
3755
3994
|
ensureGlobalStyles();
|
|
3756
3995
|
function CollabPanel({
|
|
3757
3996
|
orderId,
|
|
@@ -3760,6 +3999,7 @@ function CollabPanel({
|
|
|
3760
3999
|
showSeenBy = true,
|
|
3761
4000
|
onBack,
|
|
3762
4001
|
hidePatientName = false,
|
|
4002
|
+
onConversationChange,
|
|
3763
4003
|
className,
|
|
3764
4004
|
style
|
|
3765
4005
|
}) {
|
|
@@ -3788,6 +4028,9 @@ function CollabPanel({
|
|
|
3788
4028
|
pinMessage,
|
|
3789
4029
|
unpinMessage
|
|
3790
4030
|
} = useConversation({ orderId, patientData, participantIds });
|
|
4031
|
+
useEffect(() => {
|
|
4032
|
+
onConversationChange?.(conversation);
|
|
4033
|
+
}, [conversation, onConversationChange]);
|
|
3791
4034
|
const channelSettings = useChannelSettings({
|
|
3792
4035
|
conversationId: conversation?.id ?? null
|
|
3793
4036
|
});
|
|
@@ -3996,6 +4239,7 @@ function CollabPopup({
|
|
|
3996
4239
|
isOpen,
|
|
3997
4240
|
onClose,
|
|
3998
4241
|
onBack,
|
|
4242
|
+
onMinimize,
|
|
3999
4243
|
initialPosition,
|
|
4000
4244
|
width = 380,
|
|
4001
4245
|
height = 520,
|
|
@@ -4009,10 +4253,12 @@ function CollabPopup({
|
|
|
4009
4253
|
);
|
|
4010
4254
|
const [isDragging, setIsDragging] = useState(false);
|
|
4011
4255
|
const [isMinimized, setIsMinimized] = useState(false);
|
|
4256
|
+
const [loadedConversation, setLoadedConversation] = useState(null);
|
|
4012
4257
|
const dragOffset = useRef({ x: 0, y: 0 });
|
|
4013
4258
|
const containerRef = useRef(null);
|
|
4014
4259
|
const previouslyFocused = useRef(null);
|
|
4015
4260
|
const titleId = useId();
|
|
4261
|
+
const titleText = cleanChannelName(loadedConversation?.name) || buildChannelName(patientData);
|
|
4016
4262
|
const handleMouseDown = useCallback(
|
|
4017
4263
|
(e) => {
|
|
4018
4264
|
if (!e.target.closest("[data-drag-handle]")) return;
|
|
@@ -4109,40 +4355,62 @@ function CollabPopup({
|
|
|
4109
4355
|
"button",
|
|
4110
4356
|
{
|
|
4111
4357
|
onClick: onBack,
|
|
4112
|
-
style: styles13.
|
|
4113
|
-
"aria-label": "
|
|
4358
|
+
style: styles13.titleSquare,
|
|
4359
|
+
"aria-label": "Back to messages",
|
|
4114
4360
|
title: "Back",
|
|
4115
4361
|
type: "button",
|
|
4116
|
-
children:
|
|
4362
|
+
children: /* @__PURE__ */ jsx(BackIcon, { size: 18, color: COLOR.neutral700 })
|
|
4117
4363
|
}
|
|
4118
4364
|
),
|
|
4119
|
-
/* @__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
|
+
] }),
|
|
4120
4376
|
/* @__PURE__ */ jsxs("div", { style: styles13.titleActions, children: [
|
|
4121
4377
|
/* @__PURE__ */ jsx(
|
|
4122
4378
|
"button",
|
|
4123
4379
|
{
|
|
4124
|
-
onClick: () =>
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
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",
|
|
4128
4387
|
type: "button",
|
|
4129
|
-
children: isMinimized ? /* @__PURE__ */ jsx(
|
|
4388
|
+
children: onMinimize || !isMinimized ? /* @__PURE__ */ jsx(MinimizeIcon, { size: 18, color: COLOR.neutral700 }) : /* @__PURE__ */ jsx(ExpandIcon, { size: 18, color: COLOR.neutral700 })
|
|
4130
4389
|
}
|
|
4131
4390
|
),
|
|
4132
4391
|
/* @__PURE__ */ jsx(
|
|
4133
4392
|
"button",
|
|
4134
4393
|
{
|
|
4135
4394
|
onClick: onClose,
|
|
4136
|
-
style: styles13.
|
|
4395
|
+
style: styles13.titleSquare,
|
|
4137
4396
|
"aria-label": "Close chat",
|
|
4138
4397
|
title: "Close",
|
|
4139
4398
|
type: "button",
|
|
4140
|
-
children: /* @__PURE__ */ jsx(CloseIcon, { size:
|
|
4399
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { size: 18, color: COLOR.neutral700 })
|
|
4141
4400
|
}
|
|
4142
4401
|
)
|
|
4143
4402
|
] })
|
|
4144
4403
|
] }),
|
|
4145
|
-
!isMinimized && /* @__PURE__ */ jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsx(
|
|
4404
|
+
!isMinimized && /* @__PURE__ */ jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsx(
|
|
4405
|
+
CollabPanel,
|
|
4406
|
+
{
|
|
4407
|
+
orderId,
|
|
4408
|
+
patientData,
|
|
4409
|
+
participantIds,
|
|
4410
|
+
hidePatientName: true,
|
|
4411
|
+
onConversationChange: setLoadedConversation
|
|
4412
|
+
}
|
|
4413
|
+
) })
|
|
4146
4414
|
]
|
|
4147
4415
|
}
|
|
4148
4416
|
);
|
|
@@ -4151,51 +4419,78 @@ var styles13 = {
|
|
|
4151
4419
|
container: {
|
|
4152
4420
|
position: "fixed",
|
|
4153
4421
|
zIndex: Z_INDEX.dialog,
|
|
4154
|
-
borderRadius:
|
|
4155
|
-
boxShadow:
|
|
4422
|
+
borderRadius: "20px",
|
|
4423
|
+
boxShadow: "0 20px 48px rgba(20, 21, 28, 0.16), 0 6px 16px rgba(20, 21, 28, 0.08)",
|
|
4156
4424
|
overflow: "hidden",
|
|
4157
4425
|
display: "flex",
|
|
4158
4426
|
flexDirection: "column",
|
|
4159
4427
|
backgroundColor: COLOR.white,
|
|
4160
|
-
border: `1px solid ${COLOR.
|
|
4428
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
4161
4429
|
transition: "height 0.2s ease",
|
|
4162
4430
|
fontFamily: FONT_STACK
|
|
4163
4431
|
},
|
|
4164
4432
|
titleBar: {
|
|
4165
4433
|
display: "flex",
|
|
4166
|
-
justifyContent: "space-between",
|
|
4167
4434
|
alignItems: "center",
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
backgroundColor: COLOR.
|
|
4435
|
+
gap: SPACE.S2,
|
|
4436
|
+
padding: `10px ${SPACE.S3}`,
|
|
4437
|
+
backgroundColor: COLOR.white,
|
|
4438
|
+
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
4171
4439
|
cursor: "grab",
|
|
4172
4440
|
userSelect: "none",
|
|
4173
4441
|
flexShrink: 0
|
|
4174
4442
|
},
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
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,
|
|
4456
|
+
overflow: "hidden",
|
|
4457
|
+
textOverflow: "ellipsis",
|
|
4458
|
+
whiteSpace: "nowrap"
|
|
4459
|
+
},
|
|
4460
|
+
subRow: {
|
|
4461
|
+
display: "flex",
|
|
4462
|
+
alignItems: "center",
|
|
4463
|
+
gap: SPACE.S2,
|
|
4464
|
+
fontSize: FONT_SIZE.sm,
|
|
4465
|
+
color: COLOR.neutral500,
|
|
4179
4466
|
overflow: "hidden",
|
|
4180
4467
|
textOverflow: "ellipsis",
|
|
4181
4468
|
whiteSpace: "nowrap"
|
|
4182
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
|
+
},
|
|
4183
4477
|
titleActions: {
|
|
4184
4478
|
display: "flex",
|
|
4185
4479
|
gap: SPACE.S1,
|
|
4186
4480
|
flexShrink: 0
|
|
4187
4481
|
},
|
|
4188
|
-
|
|
4189
|
-
width:
|
|
4190
|
-
height:
|
|
4482
|
+
titleSquare: {
|
|
4483
|
+
width: "36px",
|
|
4484
|
+
height: "36px",
|
|
4191
4485
|
display: "flex",
|
|
4192
4486
|
alignItems: "center",
|
|
4193
4487
|
justifyContent: "center",
|
|
4194
|
-
backgroundColor:
|
|
4195
|
-
border:
|
|
4488
|
+
backgroundColor: COLOR.neutral100,
|
|
4489
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
4196
4490
|
borderRadius: RADIUS.md,
|
|
4197
4491
|
cursor: "pointer",
|
|
4198
|
-
color: COLOR.
|
|
4492
|
+
color: COLOR.neutral700,
|
|
4493
|
+
flexShrink: 0
|
|
4199
4494
|
},
|
|
4200
4495
|
panelWrapper: {
|
|
4201
4496
|
flex: 1,
|
|
@@ -4499,10 +4794,14 @@ function InlineMessageRow({ message }) {
|
|
|
4499
4794
|
}
|
|
4500
4795
|
function RoleDot({ role }) {
|
|
4501
4796
|
const colors = {
|
|
4502
|
-
radiologist: "#
|
|
4797
|
+
radiologist: "#4f46e5",
|
|
4798
|
+
// indigo
|
|
4503
4799
|
lab: "#2563eb",
|
|
4504
|
-
|
|
4505
|
-
|
|
4800
|
+
// brand blue
|
|
4801
|
+
physician: "#0284c7",
|
|
4802
|
+
// sky
|
|
4803
|
+
admin: "#64748b"
|
|
4804
|
+
// slate
|
|
4506
4805
|
};
|
|
4507
4806
|
return /* @__PURE__ */ jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
|
|
4508
4807
|
}
|
|
@@ -4924,6 +5223,10 @@ function ConversationListItem({
|
|
|
4924
5223
|
}) {
|
|
4925
5224
|
const hasUnread = item.unreadCount > 0;
|
|
4926
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);
|
|
4927
5230
|
return /* @__PURE__ */ jsxs(
|
|
4928
5231
|
"button",
|
|
4929
5232
|
{
|
|
@@ -4931,15 +5234,11 @@ function ConversationListItem({
|
|
|
4931
5234
|
onClick,
|
|
4932
5235
|
style: {
|
|
4933
5236
|
...styles15.container,
|
|
4934
|
-
...isSelected ? styles15.selected : {}
|
|
4935
|
-
...hasUnread ? styles15.unread : {}
|
|
5237
|
+
...isSelected ? styles15.selected : {}
|
|
4936
5238
|
},
|
|
4937
5239
|
type: "button",
|
|
4938
5240
|
children: [
|
|
4939
|
-
/* @__PURE__ */
|
|
4940
|
-
item.picture ? /* @__PURE__ */ jsx("img", { src: item.picture, alt: "", style: styles15.avatar }) : /* @__PURE__ */ jsx("div", { style: styles15.avatarFallback, children: (displayName).charAt(0).toUpperCase() }),
|
|
4941
|
-
hasUnread && /* @__PURE__ */ jsx("span", { style: styles15.unreadDot })
|
|
4942
|
-
] }),
|
|
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 }) }),
|
|
4943
5242
|
/* @__PURE__ */ jsxs("div", { style: styles15.content, children: [
|
|
4944
5243
|
/* @__PURE__ */ jsxs("div", { style: styles15.topRow, children: [
|
|
4945
5244
|
/* @__PURE__ */ jsx(
|
|
@@ -4963,101 +5262,120 @@ function ConversationListItem({
|
|
|
4963
5262
|
}
|
|
4964
5263
|
)
|
|
4965
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
|
+
] }),
|
|
4966
5273
|
/* @__PURE__ */ jsxs("div", { style: styles15.bottomRow, children: [
|
|
4967
|
-
/* @__PURE__ */ jsx(
|
|
4968
|
-
|
|
4969
|
-
{
|
|
4970
|
-
style: {
|
|
4971
|
-
...styles15.preview,
|
|
4972
|
-
...hasUnread ? styles15.previewUnread : {}
|
|
4973
|
-
},
|
|
4974
|
-
children: renderLastMessagePreview(item.lastMessage)
|
|
4975
|
-
}
|
|
4976
|
-
),
|
|
4977
|
-
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 })
|
|
4978
5276
|
] })
|
|
4979
5277
|
] })
|
|
4980
5278
|
]
|
|
4981
5279
|
}
|
|
4982
5280
|
);
|
|
4983
5281
|
}
|
|
4984
|
-
function
|
|
4985
|
-
if (!message)
|
|
4986
|
-
|
|
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) {
|
|
4987
5309
|
switch (message.type) {
|
|
4988
5310
|
case "audio":
|
|
4989
|
-
return
|
|
5311
|
+
return "Voice message";
|
|
4990
5312
|
case "image":
|
|
4991
|
-
return
|
|
5313
|
+
return message.fileName || "Image";
|
|
4992
5314
|
case "file":
|
|
4993
|
-
return
|
|
5315
|
+
return message.fileName || "File";
|
|
4994
5316
|
case "deep_link":
|
|
4995
|
-
return
|
|
4996
|
-
case "system":
|
|
4997
|
-
return message.body;
|
|
5317
|
+
return message.body || "Shared link";
|
|
4998
5318
|
default: {
|
|
4999
5319
|
const body = message.body || "";
|
|
5000
|
-
|
|
5001
|
-
return `${prefix}${preview}`;
|
|
5320
|
+
return body.length > 60 ? `${body.slice(0, 60)}\u2026` : body;
|
|
5002
5321
|
}
|
|
5003
5322
|
}
|
|
5004
5323
|
}
|
|
5324
|
+
function computeInitials2(name) {
|
|
5325
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("") || "?";
|
|
5326
|
+
}
|
|
5005
5327
|
var styles15 = {
|
|
5006
5328
|
container: {
|
|
5007
5329
|
display: "flex",
|
|
5008
|
-
alignItems: "
|
|
5009
|
-
gap:
|
|
5010
|
-
padding: `${SPACE.S3} ${SPACE.S3}`,
|
|
5330
|
+
alignItems: "flex-start",
|
|
5331
|
+
gap: "14px",
|
|
5011
5332
|
width: "100%",
|
|
5333
|
+
padding: `14px ${SPACE.S5}`,
|
|
5334
|
+
minHeight: "84px",
|
|
5012
5335
|
backgroundColor: "transparent",
|
|
5013
5336
|
border: "none",
|
|
5014
|
-
|
|
5337
|
+
borderLeft: "4px solid transparent",
|
|
5015
5338
|
cursor: "pointer",
|
|
5016
|
-
textAlign: "left"
|
|
5339
|
+
textAlign: "left",
|
|
5340
|
+
color: "inherit",
|
|
5341
|
+
fontFamily: "inherit",
|
|
5342
|
+
transition: "background-color 120ms ease"
|
|
5017
5343
|
},
|
|
5018
5344
|
selected: {
|
|
5019
|
-
backgroundColor: COLOR.primaryBg
|
|
5345
|
+
backgroundColor: COLOR.primaryBg,
|
|
5346
|
+
borderLeftColor: COLOR.primary
|
|
5020
5347
|
},
|
|
5021
|
-
unread: {},
|
|
5022
5348
|
avatarWrapper: {
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
height: SIZE.avatar,
|
|
5349
|
+
width: "52px",
|
|
5350
|
+
height: "52px",
|
|
5026
5351
|
flexShrink: 0
|
|
5027
5352
|
},
|
|
5028
|
-
|
|
5029
|
-
width:
|
|
5030
|
-
height:
|
|
5031
|
-
borderRadius: RADIUS.
|
|
5032
|
-
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)"
|
|
5033
5359
|
},
|
|
5034
|
-
|
|
5035
|
-
width:
|
|
5036
|
-
height:
|
|
5037
|
-
borderRadius: RADIUS.
|
|
5038
|
-
backgroundColor: COLOR.
|
|
5360
|
+
avatarTile: {
|
|
5361
|
+
width: "52px",
|
|
5362
|
+
height: "52px",
|
|
5363
|
+
borderRadius: RADIUS.xl,
|
|
5364
|
+
backgroundColor: COLOR.primary,
|
|
5365
|
+
color: COLOR.white,
|
|
5039
5366
|
display: "flex",
|
|
5040
5367
|
alignItems: "center",
|
|
5041
5368
|
justifyContent: "center",
|
|
5042
|
-
fontSize: FONT_SIZE.
|
|
5043
|
-
fontWeight: FONT_WEIGHT.
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
unreadDot: {
|
|
5047
|
-
position: "absolute",
|
|
5048
|
-
top: "0",
|
|
5049
|
-
left: "0",
|
|
5050
|
-
width: SIZE.dot,
|
|
5051
|
-
height: SIZE.dot,
|
|
5052
|
-
borderRadius: RADIUS.full,
|
|
5053
|
-
backgroundColor: COLOR.primary,
|
|
5054
|
-
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)"
|
|
5055
5373
|
},
|
|
5056
5374
|
content: {
|
|
5057
5375
|
flex: 1,
|
|
5058
5376
|
display: "flex",
|
|
5059
5377
|
flexDirection: "column",
|
|
5060
|
-
gap: "
|
|
5378
|
+
gap: "3px",
|
|
5061
5379
|
minWidth: 0
|
|
5062
5380
|
},
|
|
5063
5381
|
topRow: {
|
|
@@ -5082,123 +5400,191 @@ var styles15 = {
|
|
|
5082
5400
|
time: {
|
|
5083
5401
|
fontSize: FONT_SIZE.xs,
|
|
5084
5402
|
color: COLOR.neutral500,
|
|
5403
|
+
fontVariantNumeric: "tabular-nums",
|
|
5085
5404
|
flexShrink: 0
|
|
5086
5405
|
},
|
|
5087
5406
|
timeUnread: {
|
|
5088
5407
|
color: COLOR.primary,
|
|
5089
5408
|
fontWeight: FONT_WEIGHT.semibold
|
|
5090
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
|
+
},
|
|
5091
5435
|
bottomRow: {
|
|
5092
5436
|
display: "flex",
|
|
5093
5437
|
justifyContent: "space-between",
|
|
5094
5438
|
alignItems: "center",
|
|
5095
|
-
gap: SPACE.S2
|
|
5439
|
+
gap: SPACE.S2,
|
|
5440
|
+
marginTop: "2px"
|
|
5096
5441
|
},
|
|
5097
5442
|
preview: {
|
|
5098
5443
|
fontSize: FONT_SIZE.sm,
|
|
5099
|
-
color: COLOR.
|
|
5444
|
+
color: COLOR.neutral500,
|
|
5100
5445
|
overflow: "hidden",
|
|
5101
5446
|
textOverflow: "ellipsis",
|
|
5102
5447
|
whiteSpace: "nowrap",
|
|
5103
5448
|
flex: 1,
|
|
5104
5449
|
minWidth: 0
|
|
5105
5450
|
},
|
|
5451
|
+
previewSender: {
|
|
5452
|
+
color: COLOR.neutral700,
|
|
5453
|
+
fontWeight: FONT_WEIGHT.semibold
|
|
5454
|
+
},
|
|
5106
5455
|
previewUnread: {
|
|
5107
5456
|
color: COLOR.neutral900,
|
|
5108
5457
|
fontWeight: FONT_WEIGHT.medium
|
|
5109
5458
|
},
|
|
5110
5459
|
badge: {
|
|
5111
|
-
minWidth: "
|
|
5112
|
-
height: "
|
|
5113
|
-
padding:
|
|
5460
|
+
minWidth: "22px",
|
|
5461
|
+
height: "22px",
|
|
5462
|
+
padding: "0 9px",
|
|
5114
5463
|
fontSize: FONT_SIZE.xs,
|
|
5115
|
-
fontWeight: FONT_WEIGHT.
|
|
5464
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
5116
5465
|
color: COLOR.white,
|
|
5117
|
-
backgroundColor: COLOR.
|
|
5466
|
+
backgroundColor: COLOR.danger,
|
|
5118
5467
|
borderRadius: RADIUS.pill,
|
|
5119
5468
|
display: "flex",
|
|
5120
5469
|
alignItems: "center",
|
|
5121
5470
|
justifyContent: "center",
|
|
5471
|
+
fontVariantNumeric: "tabular-nums",
|
|
5122
5472
|
flexShrink: 0
|
|
5123
5473
|
}
|
|
5124
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
|
+
}
|
|
5125
5496
|
function ConversationList({
|
|
5126
5497
|
conversations,
|
|
5127
5498
|
selectedId,
|
|
5128
5499
|
isLoading,
|
|
5129
5500
|
error,
|
|
5130
5501
|
onSelect,
|
|
5131
|
-
title = "Conversations",
|
|
5132
5502
|
className
|
|
5133
5503
|
}) {
|
|
5134
5504
|
const [query, setQuery] = useState("");
|
|
5135
|
-
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]);
|
|
5136
5518
|
const filtered = useMemo(() => {
|
|
5137
5519
|
let result = conversations;
|
|
5138
|
-
if (
|
|
5520
|
+
if (filter === "unread") {
|
|
5139
5521
|
result = result.filter((c) => c.unreadCount > 0);
|
|
5140
5522
|
}
|
|
5141
5523
|
const q = query.trim().toLowerCase();
|
|
5142
5524
|
if (q) {
|
|
5143
5525
|
result = result.filter((c) => {
|
|
5144
|
-
const patient = c.patientSnapshot?.patientName?.toLowerCase() || "";
|
|
5145
5526
|
const name = c.name.toLowerCase();
|
|
5146
|
-
|
|
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);
|
|
5147
5531
|
});
|
|
5148
5532
|
}
|
|
5149
5533
|
return result;
|
|
5150
|
-
}, [conversations, query,
|
|
5151
|
-
const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
|
|
5534
|
+
}, [conversations, query, filter]);
|
|
5152
5535
|
return /* @__PURE__ */ jsxs("div", { className, style: styles16.container, children: [
|
|
5153
|
-
/* @__PURE__ */ jsxs("div", { style: styles16.
|
|
5154
|
-
/* @__PURE__ */
|
|
5155
|
-
|
|
5156
|
-
totalUnread > 0 && /* @__PURE__ */ jsx("span", { style: styles16.totalBadge, children: totalUnread })
|
|
5157
|
-
] }),
|
|
5158
|
-
/* @__PURE__ */ jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsx(
|
|
5159
|
-
"input",
|
|
5536
|
+
/* @__PURE__ */ jsxs("div", { style: styles16.tabs, children: [
|
|
5537
|
+
/* @__PURE__ */ jsx(
|
|
5538
|
+
TabButton,
|
|
5160
5539
|
{
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
style: styles16.searchInput
|
|
5540
|
+
label: "Unread",
|
|
5541
|
+
count: unreadCount,
|
|
5542
|
+
isActive: filter === "unread",
|
|
5543
|
+
onClick: () => setFilter("unread")
|
|
5166
5544
|
}
|
|
5167
|
-
)
|
|
5168
|
-
/* @__PURE__ */
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
type: "button",
|
|
5178
|
-
children: "All"
|
|
5179
|
-
}
|
|
5180
|
-
),
|
|
5181
|
-
/* @__PURE__ */ jsxs(
|
|
5182
|
-
"button",
|
|
5183
|
-
{
|
|
5184
|
-
onClick: () => setShowUnreadOnly(true),
|
|
5185
|
-
style: {
|
|
5186
|
-
...styles16.filterButton,
|
|
5187
|
-
...showUnreadOnly ? styles16.filterButtonActive : {}
|
|
5188
|
-
},
|
|
5189
|
-
type: "button",
|
|
5190
|
-
children: [
|
|
5191
|
-
"Unread ",
|
|
5192
|
-
totalUnread > 0 && `(${totalUnread})`
|
|
5193
|
-
]
|
|
5194
|
-
}
|
|
5195
|
-
)
|
|
5196
|
-
] })
|
|
5545
|
+
),
|
|
5546
|
+
/* @__PURE__ */ jsx(
|
|
5547
|
+
TabButton,
|
|
5548
|
+
{
|
|
5549
|
+
label: "All",
|
|
5550
|
+
count: conversations.length,
|
|
5551
|
+
isActive: filter === "all",
|
|
5552
|
+
onClick: () => setFilter("all")
|
|
5553
|
+
}
|
|
5554
|
+
)
|
|
5197
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
|
+
),
|
|
5198
5581
|
/* @__PURE__ */ jsxs("div", { style: styles16.list, children: [
|
|
5199
|
-
isLoading && /* @__PURE__ */
|
|
5200
|
-
|
|
5201
|
-
|
|
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 }),
|
|
5202
5588
|
filtered.map((item) => /* @__PURE__ */ jsx(
|
|
5203
5589
|
ConversationListItem,
|
|
5204
5590
|
{
|
|
@@ -5211,95 +5597,178 @@ function ConversationList({
|
|
|
5211
5597
|
] })
|
|
5212
5598
|
] });
|
|
5213
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
|
+
}
|
|
5214
5647
|
var styles16 = {
|
|
5215
5648
|
container: {
|
|
5216
5649
|
display: "flex",
|
|
5217
5650
|
flexDirection: "column",
|
|
5218
5651
|
height: "100%",
|
|
5219
|
-
backgroundColor: COLOR.white
|
|
5220
|
-
borderRight: `1px solid ${COLOR.neutral200}`
|
|
5652
|
+
backgroundColor: COLOR.white
|
|
5221
5653
|
},
|
|
5222
|
-
header
|
|
5223
|
-
|
|
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}`,
|
|
5224
5660
|
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
5225
|
-
backgroundColor: COLOR.neutral50,
|
|
5226
5661
|
flexShrink: 0
|
|
5227
5662
|
},
|
|
5228
|
-
|
|
5229
|
-
display: "flex",
|
|
5663
|
+
tab: {
|
|
5664
|
+
display: "inline-flex",
|
|
5230
5665
|
alignItems: "center",
|
|
5231
5666
|
gap: SPACE.S2,
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
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,
|
|
5237
5675
|
fontWeight: FONT_WEIGHT.semibold,
|
|
5238
|
-
|
|
5676
|
+
transition: "background-color 120ms ease, color 120ms ease"
|
|
5239
5677
|
},
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5678
|
+
tabActive: {
|
|
5679
|
+
backgroundColor: COLOR.primaryBg,
|
|
5680
|
+
color: COLOR.primary
|
|
5681
|
+
},
|
|
5682
|
+
tabCount: {
|
|
5244
5683
|
fontSize: FONT_SIZE.xs,
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
backgroundColor: COLOR.primary,
|
|
5684
|
+
fontVariantNumeric: "tabular-nums",
|
|
5685
|
+
padding: "1px 8px",
|
|
5248
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: {
|
|
5249
5696
|
display: "flex",
|
|
5250
5697
|
alignItems: "center",
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
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"
|
|
5255
5705
|
},
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
border: `1px solid ${COLOR.neutral200}`,
|
|
5261
|
-
borderRadius: RADIUS.md,
|
|
5262
|
-
outline: "none",
|
|
5263
|
-
fontFamily: "inherit"
|
|
5706
|
+
searchFocused: {
|
|
5707
|
+
backgroundColor: COLOR.white,
|
|
5708
|
+
borderColor: COLOR.primary,
|
|
5709
|
+
boxShadow: `0 0 0 3px ${COLOR.primaryBg}`
|
|
5264
5710
|
},
|
|
5265
|
-
|
|
5711
|
+
searchIcon: {
|
|
5266
5712
|
display: "flex",
|
|
5267
|
-
|
|
5713
|
+
alignItems: "center",
|
|
5714
|
+
justifyContent: "center",
|
|
5715
|
+
flexShrink: 0
|
|
5268
5716
|
},
|
|
5269
|
-
|
|
5717
|
+
searchInput: {
|
|
5270
5718
|
flex: 1,
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
},
|
|
5279
|
-
filterButtonActive: {
|
|
5280
|
-
color: COLOR.white,
|
|
5281
|
-
backgroundColor: COLOR.primary,
|
|
5282
|
-
borderColor: COLOR.primary,
|
|
5283
|
-
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
|
|
5284
5726
|
},
|
|
5285
5727
|
list: {
|
|
5286
5728
|
flex: 1,
|
|
5287
|
-
overflowY: "auto"
|
|
5729
|
+
overflowY: "auto",
|
|
5730
|
+
padding: "4px 0 12px"
|
|
5288
5731
|
},
|
|
5289
|
-
|
|
5290
|
-
|
|
5732
|
+
loading: {
|
|
5733
|
+
display: "flex",
|
|
5734
|
+
alignItems: "center",
|
|
5735
|
+
justifyContent: "center",
|
|
5736
|
+
gap: SPACE.S2,
|
|
5737
|
+
padding: `44px ${SPACE.S5}`,
|
|
5291
5738
|
fontSize: FONT_SIZE.sm,
|
|
5292
|
-
color: COLOR.neutral500
|
|
5293
|
-
textAlign: "center"
|
|
5739
|
+
color: COLOR.neutral500
|
|
5294
5740
|
},
|
|
5295
5741
|
errorState: {
|
|
5296
5742
|
padding: SPACE.S4,
|
|
5743
|
+
margin: SPACE.S3,
|
|
5297
5744
|
fontSize: FONT_SIZE.sm,
|
|
5298
5745
|
color: COLOR.danger,
|
|
5299
5746
|
backgroundColor: COLOR.dangerBg,
|
|
5300
|
-
|
|
5747
|
+
border: `1px solid ${COLOR.dangerBorder}`,
|
|
5301
5748
|
borderRadius: RADIUS.md,
|
|
5302
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
|
|
5303
5772
|
}
|
|
5304
5773
|
};
|
|
5305
5774
|
ensureGlobalStyles();
|
|
@@ -5307,7 +5776,6 @@ var COMPACT_BREAKPOINT = 720;
|
|
|
5307
5776
|
function CollabInbox({
|
|
5308
5777
|
initialConversationId,
|
|
5309
5778
|
onSelectConversation,
|
|
5310
|
-
title,
|
|
5311
5779
|
className,
|
|
5312
5780
|
style
|
|
5313
5781
|
}) {
|
|
@@ -5344,8 +5812,7 @@ function CollabInbox({
|
|
|
5344
5812
|
selectedId,
|
|
5345
5813
|
isLoading,
|
|
5346
5814
|
error,
|
|
5347
|
-
onSelect: handleSelect
|
|
5348
|
-
title
|
|
5815
|
+
onSelect: handleSelect
|
|
5349
5816
|
}
|
|
5350
5817
|
) }),
|
|
5351
5818
|
showDetail && /* @__PURE__ */ jsx("div", { style: isCompact ? styles17.mainCompact : styles17.main, children: selected ? /* @__PURE__ */ jsx(
|
|
@@ -5358,7 +5825,7 @@ function CollabInbox({
|
|
|
5358
5825
|
onBack: isCompact ? () => setSelectedId(null) : void 0
|
|
5359
5826
|
},
|
|
5360
5827
|
selected.id
|
|
5361
|
-
) : /* @__PURE__ */ jsx(
|
|
5828
|
+
) : /* @__PURE__ */ jsx(EmptyState2, { hasAny: conversations.length > 0 }) })
|
|
5362
5829
|
]
|
|
5363
5830
|
}
|
|
5364
5831
|
);
|
|
@@ -5392,7 +5859,7 @@ function parseChannelName(name, orderId) {
|
|
|
5392
5859
|
orderId
|
|
5393
5860
|
};
|
|
5394
5861
|
}
|
|
5395
|
-
function
|
|
5862
|
+
function EmptyState2({ hasAny }) {
|
|
5396
5863
|
return /* @__PURE__ */ jsxs("div", { style: styles17.empty, children: [
|
|
5397
5864
|
/* @__PURE__ */ jsx("div", { style: styles17.emptyIcon, children: "\u{1F4AC}" }),
|
|
5398
5865
|
/* @__PURE__ */ jsx("h3", { style: styles17.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
|
|
@@ -5771,6 +6238,6 @@ function usePinnedMessages({
|
|
|
5771
6238
|
};
|
|
5772
6239
|
}
|
|
5773
6240
|
|
|
5774
|
-
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 };
|
|
5775
6242
|
//# sourceMappingURL=index.mjs.map
|
|
5776
6243
|
//# sourceMappingURL=index.mjs.map
|