@natoe/colab 0.1.3 → 0.1.5

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.js CHANGED
@@ -834,6 +834,7 @@ function useConversation({
834
834
  body,
835
835
  type: "text",
836
836
  insertedAt: (/* @__PURE__ */ new Date()).toISOString(),
837
+ status: "sending",
837
838
  ...replyTo ? {
838
839
  replyToId: replyTo.id,
839
840
  replyToSnapshot: {
@@ -849,7 +850,9 @@ function useConversation({
849
850
  try {
850
851
  await socket.sendMessage(conv.id, payload);
851
852
  } catch (err) {
852
- setMessages((prev) => prev.filter((m) => m.id !== optimistic.id));
853
+ setMessages(
854
+ (prev) => prev.map((m) => m.id === optimistic.id ? { ...m, status: "failed" } : m)
855
+ );
853
856
  config.onError?.({
854
857
  code: "SEND_FAILED",
855
858
  message: "Failed to send message",
@@ -859,6 +862,34 @@ function useConversation({
859
862
  },
860
863
  [ensureConversation, socket, replyTo, config]
861
864
  );
865
+ const retryMessage = React4.useCallback(
866
+ async (messageId) => {
867
+ if (!conversation) return;
868
+ const target = messages.find((m) => m.id === messageId);
869
+ if (!target || target.status !== "failed" || target.type !== "text") return;
870
+ setMessages(
871
+ (prev) => prev.map((m) => m.id === messageId ? { ...m, status: "sending" } : m)
872
+ );
873
+ const payload = {
874
+ body: target.body,
875
+ type: "text",
876
+ ...target.replyToId ? { replyToId: target.replyToId } : {}
877
+ };
878
+ try {
879
+ await socket.sendMessage(conversation.id, payload);
880
+ } catch (err) {
881
+ setMessages(
882
+ (prev) => prev.map((m) => m.id === messageId ? { ...m, status: "failed" } : m)
883
+ );
884
+ config.onError?.({
885
+ code: "SEND_FAILED",
886
+ message: "Failed to send message",
887
+ details: err
888
+ });
889
+ }
890
+ },
891
+ [conversation, messages, socket, config]
892
+ );
862
893
  const sendAudioMessage = React4.useCallback(
863
894
  async (audioBlob, duration) => {
864
895
  if (!config.onUploadFile) return;
@@ -951,6 +982,7 @@ function useConversation({
951
982
  message: "Failed to pin message",
952
983
  details: err
953
984
  });
985
+ throw err;
954
986
  }
955
987
  },
956
988
  [conversation, pinMessageApi, config]
@@ -966,6 +998,7 @@ function useConversation({
966
998
  message: "Failed to unpin message",
967
999
  details: err
968
1000
  });
1001
+ throw err;
969
1002
  }
970
1003
  },
971
1004
  [conversation, unpinMessageApi, config]
@@ -983,6 +1016,7 @@ function useConversation({
983
1016
  replyTo,
984
1017
  setReplyTo,
985
1018
  sendMessage,
1019
+ retryMessage,
986
1020
  sendAudioMessage,
987
1021
  sendFileMessage,
988
1022
  sendDeepLink,
@@ -1345,91 +1379,247 @@ var styles3 = {
1345
1379
  textDecoration: "underline"
1346
1380
  }
1347
1381
  };
1382
+ function ReplyIcon({ size = 18, color = "currentColor" }) {
1383
+ return /* @__PURE__ */ jsxRuntime.jsx(
1384
+ "svg",
1385
+ {
1386
+ xmlns: "http://www.w3.org/2000/svg",
1387
+ width: size,
1388
+ height: size,
1389
+ viewBox: "0 0 24 24",
1390
+ fill: color,
1391
+ "aria-hidden": "true",
1392
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z" })
1393
+ }
1394
+ );
1395
+ }
1396
+ function PinIcon({ size = 14, color = "currentColor" }) {
1397
+ return /* @__PURE__ */ jsxRuntime.jsx(
1398
+ "svg",
1399
+ {
1400
+ xmlns: "http://www.w3.org/2000/svg",
1401
+ width: size,
1402
+ height: size,
1403
+ viewBox: "0 0 24 24",
1404
+ fill: color,
1405
+ "aria-hidden": "true",
1406
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 9V4l1 0c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1l1 0v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z" })
1407
+ }
1408
+ );
1409
+ }
1410
+ function CopyIcon({ size = 18, color = "currentColor" }) {
1411
+ return /* @__PURE__ */ jsxRuntime.jsx(
1412
+ "svg",
1413
+ {
1414
+ xmlns: "http://www.w3.org/2000/svg",
1415
+ width: size,
1416
+ height: size,
1417
+ viewBox: "0 0 24 24",
1418
+ fill: color,
1419
+ "aria-hidden": "true",
1420
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" })
1421
+ }
1422
+ );
1423
+ }
1424
+ function MoreIcon({ size = 18, color = "currentColor" }) {
1425
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1426
+ "svg",
1427
+ {
1428
+ xmlns: "http://www.w3.org/2000/svg",
1429
+ width: size,
1430
+ height: size,
1431
+ viewBox: "0 0 24 24",
1432
+ fill: color,
1433
+ "aria-hidden": "true",
1434
+ children: [
1435
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "5", r: "2" }),
1436
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "2" }),
1437
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "19", r: "2" })
1438
+ ]
1439
+ }
1440
+ );
1441
+ }
1348
1442
  function MessageActionsMenu({
1349
1443
  message,
1350
1444
  onReply,
1351
1445
  onPin,
1352
1446
  onUnpin,
1353
1447
  onCopy,
1354
- visible,
1355
1448
  pinDisabled = false,
1449
+ anchorRight = false,
1356
1450
  className
1357
1451
  }) {
1358
- if (!visible) return null;
1452
+ const [isOpen, setIsOpen] = React4.useState(false);
1453
+ const wrapperRef = React4.useRef(null);
1454
+ const triggerRef = React4.useRef(null);
1359
1455
  const isPinned = !!message.isPinned;
1360
1456
  const canCopy = message.type === "text" && !!message.body;
1361
- const handleCopy = () => {
1362
- if (!onCopy) return;
1363
- onCopy(message.body);
1457
+ React4.useEffect(() => {
1458
+ if (!isOpen) return;
1459
+ const handleClick = (e) => {
1460
+ if (!wrapperRef.current?.contains(e.target)) {
1461
+ setIsOpen(false);
1462
+ }
1463
+ };
1464
+ const handleKey = (e) => {
1465
+ if (e.key === "Escape") {
1466
+ setIsOpen(false);
1467
+ triggerRef.current?.focus();
1468
+ }
1469
+ };
1470
+ document.addEventListener("mousedown", handleClick);
1471
+ document.addEventListener("keydown", handleKey);
1472
+ return () => {
1473
+ document.removeEventListener("mousedown", handleClick);
1474
+ document.removeEventListener("keydown", handleKey);
1475
+ };
1476
+ }, [isOpen]);
1477
+ const run = (fn) => {
1478
+ setIsOpen(false);
1479
+ fn();
1364
1480
  };
1365
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles4.container, children: [
1481
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapperRef, className, style: styles4.wrapper, children: [
1366
1482
  /* @__PURE__ */ jsxRuntime.jsx(
1367
1483
  "button",
1368
1484
  {
1369
- onClick: () => onReply(message),
1370
- style: styles4.button,
1371
- title: "Reply",
1485
+ ref: triggerRef,
1372
1486
  type: "button",
1373
- children: "\u21A9"
1487
+ onClick: (e) => {
1488
+ e.stopPropagation();
1489
+ setIsOpen((v) => !v);
1490
+ },
1491
+ "aria-label": "Message actions",
1492
+ "aria-haspopup": "menu",
1493
+ "aria-expanded": isOpen ? "true" : "false",
1494
+ title: "Message actions",
1495
+ style: styles4.trigger,
1496
+ children: /* @__PURE__ */ jsxRuntime.jsx(MoreIcon, { size: 18, color: "#4b5563" })
1374
1497
  }
1375
1498
  ),
1376
- isPinned ? /* @__PURE__ */ jsxRuntime.jsx(
1377
- "button",
1378
- {
1379
- onClick: () => onUnpin(message.id),
1380
- style: styles4.button,
1381
- title: "Unpin",
1382
- type: "button",
1383
- children: "\u{1F4CC}"
1384
- }
1385
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1386
- "button",
1499
+ isOpen && /* @__PURE__ */ jsxRuntime.jsxs(
1500
+ "div",
1387
1501
  {
1388
- onClick: () => onPin(message.id),
1502
+ role: "menu",
1503
+ "aria-label": "Message actions",
1389
1504
  style: {
1390
- ...styles4.button,
1391
- opacity: pinDisabled ? 0.4 : 1,
1392
- cursor: pinDisabled ? "not-allowed" : "pointer"
1505
+ ...styles4.menu,
1506
+ ...anchorRight ? styles4.menuRight : styles4.menuLeft
1393
1507
  },
1394
- disabled: pinDisabled,
1395
- title: pinDisabled ? "Pin limit reached (max 3)" : "Pin",
1396
- type: "button",
1397
- children: "\u{1F4CC}"
1398
- }
1399
- ),
1400
- canCopy && onCopy && /* @__PURE__ */ jsxRuntime.jsx(
1401
- "button",
1402
- {
1403
- onClick: handleCopy,
1404
- style: styles4.button,
1405
- title: "Copy text",
1406
- type: "button",
1407
- children: "\u2398"
1508
+ children: [
1509
+ /* @__PURE__ */ jsxRuntime.jsxs(
1510
+ "button",
1511
+ {
1512
+ type: "button",
1513
+ role: "menuitem",
1514
+ onClick: () => run(() => onReply(message)),
1515
+ style: styles4.item,
1516
+ children: [
1517
+ /* @__PURE__ */ jsxRuntime.jsx(ReplyIcon, { size: 18, color: "#374151" }),
1518
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reply" })
1519
+ ]
1520
+ }
1521
+ ),
1522
+ isPinned ? /* @__PURE__ */ jsxRuntime.jsxs(
1523
+ "button",
1524
+ {
1525
+ type: "button",
1526
+ role: "menuitem",
1527
+ onClick: () => run(() => onUnpin(message.id)),
1528
+ style: styles4.item,
1529
+ children: [
1530
+ /* @__PURE__ */ jsxRuntime.jsx(PinIcon, { size: 16, color: "#374151" }),
1531
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Unpin" })
1532
+ ]
1533
+ }
1534
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
1535
+ "button",
1536
+ {
1537
+ type: "button",
1538
+ role: "menuitem",
1539
+ onClick: () => run(() => onPin(message.id)),
1540
+ disabled: pinDisabled,
1541
+ style: {
1542
+ ...styles4.item,
1543
+ ...pinDisabled ? styles4.itemDisabled : {}
1544
+ },
1545
+ title: pinDisabled ? "Pin limit reached (max 3)" : void 0,
1546
+ children: [
1547
+ /* @__PURE__ */ jsxRuntime.jsx(PinIcon, { size: 16, color: "#374151" }),
1548
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: pinDisabled ? "Pin (limit reached)" : "Pin" })
1549
+ ]
1550
+ }
1551
+ ),
1552
+ canCopy && onCopy && /* @__PURE__ */ jsxRuntime.jsxs(
1553
+ "button",
1554
+ {
1555
+ type: "button",
1556
+ role: "menuitem",
1557
+ onClick: () => run(() => onCopy(message.body)),
1558
+ style: styles4.item,
1559
+ children: [
1560
+ /* @__PURE__ */ jsxRuntime.jsx(CopyIcon, { size: 16, color: "#374151" }),
1561
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Copy text" })
1562
+ ]
1563
+ }
1564
+ )
1565
+ ]
1408
1566
  }
1409
1567
  )
1410
1568
  ] });
1411
1569
  }
1412
1570
  var styles4 = {
1413
- container: {
1571
+ wrapper: {
1572
+ position: "relative",
1573
+ display: "inline-block"
1574
+ },
1575
+ trigger: {
1576
+ width: "36px",
1577
+ height: "36px",
1414
1578
  display: "flex",
1415
- gap: "2px",
1416
- padding: "2px",
1579
+ alignItems: "center",
1580
+ justifyContent: "center",
1581
+ backgroundColor: "transparent",
1582
+ border: "none",
1583
+ borderRadius: "50%",
1584
+ cursor: "pointer",
1585
+ color: "#4b5563"
1586
+ },
1587
+ menu: {
1588
+ position: "absolute",
1589
+ top: "100%",
1590
+ marginTop: "4px",
1591
+ minWidth: "160px",
1417
1592
  backgroundColor: "#ffffff",
1418
1593
  border: "1px solid #e5e7eb",
1419
- borderRadius: "20px",
1420
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.08)"
1594
+ borderRadius: "10px",
1595
+ boxShadow: "0 6px 18px rgba(0, 0, 0, 0.12)",
1596
+ padding: "4px",
1597
+ zIndex: 20
1421
1598
  },
1422
- button: {
1423
- width: "24px",
1424
- height: "24px",
1599
+ menuLeft: {
1600
+ left: 0
1601
+ },
1602
+ menuRight: {
1603
+ right: 0
1604
+ },
1605
+ item: {
1425
1606
  display: "flex",
1426
1607
  alignItems: "center",
1427
- justifyContent: "center",
1428
- fontSize: "12px",
1608
+ gap: "10px",
1609
+ width: "100%",
1610
+ minHeight: "40px",
1611
+ padding: "8px 12px",
1612
+ fontSize: "14px",
1613
+ color: "#111827",
1429
1614
  backgroundColor: "transparent",
1430
1615
  border: "none",
1431
- borderRadius: "50%",
1432
- cursor: "pointer"
1616
+ borderRadius: "6px",
1617
+ cursor: "pointer",
1618
+ textAlign: "left"
1619
+ },
1620
+ itemDisabled: {
1621
+ color: "#9ca3af",
1622
+ cursor: "not-allowed"
1433
1623
  }
1434
1624
  };
1435
1625
  function FileIcon({ size = 18, color = "currentColor" }) {
@@ -1446,7 +1636,7 @@ function FileIcon({ size = 18, color = "currentColor" }) {
1446
1636
  }
1447
1637
  );
1448
1638
  }
1449
- function PinIcon({ size = 14, color = "currentColor" }) {
1639
+ function AlertIcon({ size = 14, color = "currentColor" }) {
1450
1640
  return /* @__PURE__ */ jsxRuntime.jsx(
1451
1641
  "svg",
1452
1642
  {
@@ -1456,10 +1646,38 @@ function PinIcon({ size = 14, color = "currentColor" }) {
1456
1646
  viewBox: "0 0 24 24",
1457
1647
  fill: color,
1458
1648
  "aria-hidden": "true",
1459
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 9V4l1 0c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1l1 0v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z" })
1649
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" })
1460
1650
  }
1461
1651
  );
1462
1652
  }
1653
+ function Spinner({ size = 16, color = "#6b7280", thickness = 2 }) {
1654
+ return /* @__PURE__ */ jsxRuntime.jsx(
1655
+ "span",
1656
+ {
1657
+ role: "status",
1658
+ "aria-label": "Loading",
1659
+ style: {
1660
+ display: "inline-block",
1661
+ width: size,
1662
+ height: size,
1663
+ border: `${thickness}px solid ${color}33`,
1664
+ borderTopColor: color,
1665
+ borderRadius: "50%",
1666
+ animation: "natoe-colab-spin 800ms linear infinite",
1667
+ verticalAlign: "middle"
1668
+ }
1669
+ }
1670
+ );
1671
+ }
1672
+ if (typeof document !== "undefined") {
1673
+ const existing = document.getElementById("natoe-colab-spin-keyframes");
1674
+ if (!existing) {
1675
+ const style = document.createElement("style");
1676
+ style.id = "natoe-colab-spin-keyframes";
1677
+ style.textContent = `@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }`;
1678
+ document.head.appendChild(style);
1679
+ }
1680
+ }
1463
1681
  var ROLE_LABELS = {
1464
1682
  radiologist: "Radiologist",
1465
1683
  lab: "Imaging Center",
@@ -1478,15 +1696,30 @@ function MessageBubble({
1478
1696
  onUnpin,
1479
1697
  onCopy,
1480
1698
  onReplyJumpTo,
1699
+ onRetry,
1481
1700
  pinDisabled = false,
1482
1701
  className
1483
1702
  }) {
1484
- const [isHovered, setIsHovered] = React4.useState(false);
1485
1703
  if (message.type === "system") {
1486
1704
  return /* @__PURE__ */ jsxRuntime.jsx(SystemBubble, { message });
1487
1705
  }
1488
1706
  const hasActions = !!(onReply || onPin || onUnpin || onCopy);
1489
- return /* @__PURE__ */ jsxRuntime.jsx(
1707
+ const actionsSlot = hasActions ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.actionsSlot, children: /* @__PURE__ */ jsxRuntime.jsx(
1708
+ MessageActionsMenu,
1709
+ {
1710
+ message,
1711
+ onReply: onReply ?? (() => {
1712
+ }),
1713
+ onPin: onPin ?? (() => {
1714
+ }),
1715
+ onUnpin: onUnpin ?? (() => {
1716
+ }),
1717
+ onCopy,
1718
+ pinDisabled,
1719
+ anchorRight: !isOwn
1720
+ }
1721
+ ) }) : null;
1722
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1490
1723
  "div",
1491
1724
  {
1492
1725
  className,
@@ -1494,10 +1727,9 @@ function MessageBubble({
1494
1727
  ...styles5.wrapper,
1495
1728
  justifyContent: isOwn ? "flex-end" : "flex-start"
1496
1729
  },
1497
- onMouseEnter: () => setIsHovered(true),
1498
- onMouseLeave: () => setIsHovered(false),
1499
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.bubbleWrapper, children: [
1500
- /* @__PURE__ */ jsxRuntime.jsxs(
1730
+ children: [
1731
+ isOwn && actionsSlot,
1732
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.bubbleWrapper, children: /* @__PURE__ */ jsxRuntime.jsxs(
1501
1733
  "div",
1502
1734
  {
1503
1735
  style: {
@@ -1527,7 +1759,25 @@ function MessageBubble({
1527
1759
  message.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
1528
1760
  message.type === "deep_link" && /* @__PURE__ */ jsxRuntime.jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
1529
1761
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
1530
- showSeenBy && isOwn && /* @__PURE__ */ jsxRuntime.jsx(
1762
+ isOwn && message.status === "sending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
1763
+ /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 12, color: "rgba(255,255,255,0.85)" }),
1764
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Sending\u2026" })
1765
+ ] }),
1766
+ isOwn && message.status === "failed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
1767
+ /* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { size: 12, color: "#fecaca" }),
1768
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Not sent" }),
1769
+ onRetry && /* @__PURE__ */ jsxRuntime.jsx(
1770
+ "button",
1771
+ {
1772
+ type: "button",
1773
+ onClick: () => onRetry(message.id),
1774
+ style: styles5.retryButton,
1775
+ "aria-label": "Retry sending message",
1776
+ children: "Retry"
1777
+ }
1778
+ )
1779
+ ] }),
1780
+ showSeenBy && isOwn && !message.status && /* @__PURE__ */ jsxRuntime.jsx(
1531
1781
  SeenByIndicator,
1532
1782
  {
1533
1783
  readBy: message.readBy ?? [],
@@ -1538,33 +1788,9 @@ function MessageBubble({
1538
1788
  )
1539
1789
  ]
1540
1790
  }
1541
- ),
1542
- hasActions && /* @__PURE__ */ jsxRuntime.jsx(
1543
- "div",
1544
- {
1545
- style: {
1546
- ...styles5.actionsWrapper,
1547
- [isOwn ? "right" : "left"]: "100%",
1548
- [isOwn ? "marginRight" : "marginLeft"]: "6px"
1549
- },
1550
- children: /* @__PURE__ */ jsxRuntime.jsx(
1551
- MessageActionsMenu,
1552
- {
1553
- message,
1554
- onReply: onReply ?? (() => {
1555
- }),
1556
- onPin: onPin ?? (() => {
1557
- }),
1558
- onUnpin: onUnpin ?? (() => {
1559
- }),
1560
- onCopy,
1561
- visible: isHovered,
1562
- pinDisabled
1563
- }
1564
- )
1565
- }
1566
- )
1567
- ] })
1791
+ ) }),
1792
+ !isOwn && actionsSlot
1793
+ ]
1568
1794
  }
1569
1795
  );
1570
1796
  }
@@ -1661,6 +1887,8 @@ function escapeRegex2(string) {
1661
1887
  var styles5 = {
1662
1888
  wrapper: {
1663
1889
  display: "flex",
1890
+ alignItems: "flex-end",
1891
+ gap: "4px",
1664
1892
  marginBottom: "8px",
1665
1893
  paddingLeft: "16px",
1666
1894
  paddingRight: "16px"
@@ -1669,6 +1897,10 @@ var styles5 = {
1669
1897
  position: "relative",
1670
1898
  maxWidth: "75%"
1671
1899
  },
1900
+ actionsSlot: {
1901
+ flexShrink: 0,
1902
+ alignSelf: "flex-end"
1903
+ },
1672
1904
  bubble: {
1673
1905
  padding: "10px 14px",
1674
1906
  borderRadius: "12px",
@@ -1722,11 +1954,27 @@ var styles5 = {
1722
1954
  marginTop: "4px",
1723
1955
  textAlign: "right"
1724
1956
  },
1725
- actionsWrapper: {
1726
- position: "absolute",
1727
- top: "50%",
1728
- transform: "translateY(-50%)",
1729
- zIndex: 10
1957
+ statusRow: {
1958
+ display: "flex",
1959
+ alignItems: "center",
1960
+ gap: "6px",
1961
+ marginTop: "4px",
1962
+ fontSize: "12px",
1963
+ justifyContent: "flex-end",
1964
+ color: "rgba(255, 255, 255, 0.9)"
1965
+ },
1966
+ statusText: {
1967
+ opacity: 0.9
1968
+ },
1969
+ retryButton: {
1970
+ background: "transparent",
1971
+ border: "none",
1972
+ color: "#ffffff",
1973
+ fontWeight: 600,
1974
+ fontSize: "12px",
1975
+ textDecoration: "underline",
1976
+ cursor: "pointer",
1977
+ padding: "0 2px"
1730
1978
  },
1731
1979
  audioContainer: {
1732
1980
  display: "flex",
@@ -1800,6 +2048,44 @@ var styles5 = {
1800
2048
  color: "#9ca3af"
1801
2049
  }
1802
2050
  };
2051
+ function ChatIllustration({ size = 96 }) {
2052
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2053
+ "svg",
2054
+ {
2055
+ xmlns: "http://www.w3.org/2000/svg",
2056
+ width: size,
2057
+ height: size,
2058
+ viewBox: "0 0 120 120",
2059
+ fill: "none",
2060
+ "aria-hidden": "true",
2061
+ children: [
2062
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "60", cy: "60", r: "56", fill: "#eff6ff" }),
2063
+ /* @__PURE__ */ jsxRuntime.jsx(
2064
+ "path",
2065
+ {
2066
+ d: "M28 44a10 10 0 0 1 10-10h28a10 10 0 0 1 10 10v18a10 10 0 0 1-10 10H46l-10 8v-8h2a10 10 0 0 1-10-10V44Z",
2067
+ fill: "#ffffff",
2068
+ stroke: "#2563eb",
2069
+ strokeWidth: "2.5"
2070
+ }
2071
+ ),
2072
+ /* @__PURE__ */ jsxRuntime.jsx(
2073
+ "path",
2074
+ {
2075
+ d: "M52 60a8 8 0 0 1 8-8h26a8 8 0 0 1 8 8v14a8 8 0 0 1-8 8H72l8 8v-8h6a8 8 0 0 0 0-30Z",
2076
+ fill: "#dbeafe",
2077
+ stroke: "#2563eb",
2078
+ strokeWidth: "2.5"
2079
+ }
2080
+ ),
2081
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "48", cy: "53", r: "2.5", fill: "#2563eb" }),
2082
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "58", cy: "53", r: "2.5", fill: "#2563eb" }),
2083
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "68", cy: "68", r: "2.5", fill: "#2563eb" }),
2084
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "78", cy: "68", r: "2.5", fill: "#2563eb" })
2085
+ ]
2086
+ }
2087
+ );
2088
+ }
1803
2089
 
1804
2090
  // src/core/dateLabels.ts
1805
2091
  var SHORT_MONTHS = [
@@ -1891,6 +2177,7 @@ var MessageList = React4.forwardRef(function MessageList2({
1891
2177
  onPin,
1892
2178
  onUnpin,
1893
2179
  onCopy,
2180
+ onRetry,
1894
2181
  pinDisabled,
1895
2182
  className
1896
2183
  }, ref) {
@@ -1955,12 +2242,17 @@ var MessageList = React4.forwardRef(function MessageList2({
1955
2242
  style: styles6.container,
1956
2243
  onScroll: handleScroll,
1957
2244
  children: [
1958
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.loadingMore, children: "Loading earlier messages..." }),
2245
+ isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.loadingMore, children: [
2246
+ /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
2247
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading earlier messages\u2026" })
2248
+ ] }),
1959
2249
  hasMore && !isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onLoadMore, style: styles6.loadMoreButton, type: "button", children: "Load earlier messages" }),
1960
2250
  messages.length === 0 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.empty, children: [
2251
+ /* @__PURE__ */ jsxRuntime.jsx(ChatIllustration, { size: 104 }),
1961
2252
  /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptyTitle, children: "No messages yet" }),
1962
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation about this study" })
2253
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation \u2014 everyone on this case will see what you write." })
1963
2254
  ] }),
2255
+ messages.length === 0 && isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.firstLoad, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 20 }) }),
1964
2256
  messages.map((message, index) => {
1965
2257
  const currentBucket = dayBucketKey(message.insertedAt);
1966
2258
  const prevBucket = index === 0 ? null : dayBucketKey(messages[index - 1].insertedAt);
@@ -1980,6 +2272,7 @@ var MessageList = React4.forwardRef(function MessageList2({
1980
2272
  onPin,
1981
2273
  onUnpin,
1982
2274
  onCopy,
2275
+ onRetry,
1983
2276
  pinDisabled
1984
2277
  }
1985
2278
  ) })
@@ -2008,11 +2301,20 @@ var styles6 = {
2008
2301
  paddingBottom: "8px"
2009
2302
  },
2010
2303
  loadingMore: {
2011
- textAlign: "center",
2304
+ display: "flex",
2305
+ alignItems: "center",
2306
+ justifyContent: "center",
2307
+ gap: "8px",
2012
2308
  padding: "12px",
2013
2309
  fontSize: "14px",
2014
2310
  color: "#6b7280"
2015
2311
  },
2312
+ firstLoad: {
2313
+ display: "flex",
2314
+ alignItems: "center",
2315
+ justifyContent: "center",
2316
+ padding: "48px 16px"
2317
+ },
2016
2318
  loadMoreButton: {
2017
2319
  display: "block",
2018
2320
  margin: "0 auto 12px",
@@ -2037,11 +2339,14 @@ var styles6 = {
2037
2339
  fontSize: "16px",
2038
2340
  fontWeight: 600,
2039
2341
  color: "#374151",
2040
- margin: "0 0 4px"
2342
+ margin: "14px 0 4px"
2041
2343
  },
2042
2344
  emptySubtitle: {
2043
2345
  fontSize: "14px",
2044
- margin: 0
2346
+ margin: 0,
2347
+ maxWidth: "280px",
2348
+ lineHeight: 1.45,
2349
+ textAlign: "center"
2045
2350
  },
2046
2351
  typingIndicator: {
2047
2352
  padding: "4px 16px 8px",
@@ -2320,7 +2625,18 @@ function MessageInput({
2320
2625
  type: "file",
2321
2626
  onChange: handleFileSelect,
2322
2627
  style: { display: "none" },
2323
- accept: [...SUPPORTED_IMAGE_TYPES, "application/pdf", ".doc", ".docx"].join(",")
2628
+ accept: [
2629
+ ...SUPPORTED_IMAGE_TYPES,
2630
+ "application/pdf",
2631
+ ".doc",
2632
+ ".docx",
2633
+ ".xls",
2634
+ ".xlsx",
2635
+ ".csv",
2636
+ ".txt",
2637
+ ".heic",
2638
+ ".heif"
2639
+ ].join(",")
2324
2640
  }
2325
2641
  ),
2326
2642
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3045,6 +3361,64 @@ var styles11 = {
3045
3361
  flexShrink: 0
3046
3362
  }
3047
3363
  };
3364
+ function Toast({ toast, onDismiss, durationMs = 4e3 }) {
3365
+ React4.useEffect(() => {
3366
+ if (!toast) return;
3367
+ const timer = setTimeout(onDismiss, durationMs);
3368
+ return () => clearTimeout(timer);
3369
+ }, [toast, onDismiss, durationMs]);
3370
+ if (!toast) return null;
3371
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles12.container, role: "status", "aria-live": "polite", children: [
3372
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles12.message, children: toast.message }),
3373
+ toast.actionLabel && toast.onAction && /* @__PURE__ */ jsxRuntime.jsx(
3374
+ "button",
3375
+ {
3376
+ type: "button",
3377
+ onClick: () => {
3378
+ toast.onAction?.();
3379
+ onDismiss();
3380
+ },
3381
+ style: styles12.action,
3382
+ children: toast.actionLabel
3383
+ }
3384
+ )
3385
+ ] });
3386
+ }
3387
+ var styles12 = {
3388
+ container: {
3389
+ position: "absolute",
3390
+ bottom: "76px",
3391
+ left: "50%",
3392
+ transform: "translateX(-50%)",
3393
+ display: "flex",
3394
+ alignItems: "center",
3395
+ gap: "12px",
3396
+ padding: "10px 14px",
3397
+ backgroundColor: "#1e293b",
3398
+ color: "#ffffff",
3399
+ borderRadius: "8px",
3400
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.18)",
3401
+ fontSize: "14px",
3402
+ maxWidth: "90%",
3403
+ zIndex: 20
3404
+ },
3405
+ message: {
3406
+ whiteSpace: "nowrap",
3407
+ overflow: "hidden",
3408
+ textOverflow: "ellipsis"
3409
+ },
3410
+ action: {
3411
+ background: "transparent",
3412
+ border: "none",
3413
+ color: "#93c5fd",
3414
+ fontWeight: 600,
3415
+ fontSize: "14px",
3416
+ cursor: "pointer",
3417
+ padding: "4px 6px",
3418
+ textTransform: "uppercase",
3419
+ letterSpacing: "0.4px"
3420
+ }
3421
+ };
3048
3422
  function CollabPanel({
3049
3423
  orderId,
3050
3424
  patientData,
@@ -3055,6 +3429,7 @@ function CollabPanel({
3055
3429
  }) {
3056
3430
  const { config } = useCollab();
3057
3431
  const [showSettings, setShowSettings] = React4.useState(false);
3432
+ const [toast, setToast] = React4.useState(null);
3058
3433
  const messageListRef = React4.useRef(null);
3059
3434
  const {
3060
3435
  conversation,
@@ -3068,6 +3443,7 @@ function CollabPanel({
3068
3443
  replyTo,
3069
3444
  setReplyTo,
3070
3445
  sendMessage,
3446
+ retryMessage,
3071
3447
  sendAudioMessage,
3072
3448
  sendFileMessage,
3073
3449
  sendTyping,
@@ -3092,10 +3468,33 @@ function CollabPanel({
3092
3468
  try {
3093
3469
  if (navigator.clipboard) {
3094
3470
  await navigator.clipboard.writeText(text);
3471
+ setToast({ message: "Copied to clipboard" });
3095
3472
  }
3096
3473
  } catch {
3097
3474
  }
3098
3475
  };
3476
+ const handlePin = async (messageId) => {
3477
+ try {
3478
+ await pinMessage(messageId);
3479
+ setToast({
3480
+ message: "Pinned",
3481
+ actionLabel: "Undo",
3482
+ onAction: () => {
3483
+ void unpinMessage(messageId);
3484
+ }
3485
+ });
3486
+ } catch {
3487
+ setToast({ message: "Could not pin message" });
3488
+ }
3489
+ };
3490
+ const handleUnpin = async (messageId) => {
3491
+ try {
3492
+ await unpinMessage(messageId);
3493
+ setToast({ message: "Unpinned" });
3494
+ } catch {
3495
+ setToast({ message: "Could not unpin message" });
3496
+ }
3497
+ };
3099
3498
  const pinDisabled = pinnedMessages.length >= MAX_PINNED_MESSAGES;
3100
3499
  if (error) {
3101
3500
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyles.errorState, children: [
@@ -3106,78 +3505,83 @@ function CollabPanel({
3106
3505
  if (isLoading && !conversation) {
3107
3506
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: panelStyles.loadingState, children: "Loading conversation..." }) });
3108
3507
  }
3109
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: showSettings && conversation ? /* @__PURE__ */ jsxRuntime.jsx(
3110
- ChannelSettings,
3111
- {
3112
- conversationId: conversation.id,
3113
- channelName: conversation.name,
3114
- channelPicture: conversation.picture,
3115
- participants,
3116
- currentUserId: config.userId,
3117
- isAdmin: channelSettings.isAdmin,
3118
- isUpdating: channelSettings.isUpdating,
3119
- error: channelSettings.error,
3120
- onUpdateChannel: channelSettings.updateChannel,
3121
- onInviteUser: channelSettings.inviteUser,
3122
- onRemoveUser: channelSettings.removeUser,
3123
- onLeaveChannel: channelSettings.leaveChannel,
3124
- onDeleteChannel: channelSettings.deleteChannel,
3125
- onClose: () => setShowSettings(false)
3126
- }
3127
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3128
- /* @__PURE__ */ jsxRuntime.jsx(
3129
- PatientHeader,
3508
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...panelStyles.container, ...style }, children: [
3509
+ showSettings && conversation ? /* @__PURE__ */ jsxRuntime.jsx(
3510
+ ChannelSettings,
3130
3511
  {
3131
- patientData,
3512
+ conversationId: conversation.id,
3513
+ channelName: conversation.name,
3514
+ channelPicture: conversation.picture,
3132
3515
  participants,
3133
- onOpenDicom: handleOpenDicom,
3134
- onOpenSettings: () => setShowSettings(true)
3135
- }
3136
- ),
3137
- pinnedMessages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
3138
- PinnedMessagesBar,
3139
- {
3140
- pinnedMessages,
3141
- onJumpTo: handleJumpToMessage,
3142
- onUnpin: unpinMessage
3143
- }
3144
- ),
3145
- /* @__PURE__ */ jsxRuntime.jsx(
3146
- MessageList,
3147
- {
3148
- ref: messageListRef,
3149
- messages,
3150
3516
  currentUserId: config.userId,
3151
- participants,
3152
- showSeenBy,
3153
- typingUsers,
3154
- hasMore,
3155
- isLoading,
3156
- onLoadMore: loadMoreMessages,
3157
- onDeepLinkClick: handleDeepLink,
3158
- onMessageVisible: markAsRead,
3159
- onReply: setReplyTo,
3160
- onPin: pinMessage,
3161
- onUnpin: unpinMessage,
3162
- onCopy: handleCopy,
3163
- pinDisabled
3517
+ isAdmin: channelSettings.isAdmin,
3518
+ isUpdating: channelSettings.isUpdating,
3519
+ error: channelSettings.error,
3520
+ onUpdateChannel: channelSettings.updateChannel,
3521
+ onInviteUser: channelSettings.inviteUser,
3522
+ onRemoveUser: channelSettings.removeUser,
3523
+ onLeaveChannel: channelSettings.leaveChannel,
3524
+ onDeleteChannel: channelSettings.deleteChannel,
3525
+ onClose: () => setShowSettings(false)
3164
3526
  }
3165
- ),
3166
- /* @__PURE__ */ jsxRuntime.jsx(
3167
- MessageInput,
3168
- {
3169
- onSendText: sendMessage,
3170
- onSendAudio: sendAudioMessage,
3171
- onSendFile: sendFileMessage,
3172
- onTyping: sendTyping,
3173
- replyTo,
3174
- onCancelReply: () => setReplyTo(null)
3175
- }
3176
- )
3177
- ] }) });
3527
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3528
+ /* @__PURE__ */ jsxRuntime.jsx(
3529
+ PatientHeader,
3530
+ {
3531
+ patientData,
3532
+ participants,
3533
+ onOpenDicom: handleOpenDicom,
3534
+ onOpenSettings: () => setShowSettings(true)
3535
+ }
3536
+ ),
3537
+ pinnedMessages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
3538
+ PinnedMessagesBar,
3539
+ {
3540
+ pinnedMessages,
3541
+ onJumpTo: handleJumpToMessage,
3542
+ onUnpin: handleUnpin
3543
+ }
3544
+ ),
3545
+ /* @__PURE__ */ jsxRuntime.jsx(
3546
+ MessageList,
3547
+ {
3548
+ ref: messageListRef,
3549
+ messages,
3550
+ currentUserId: config.userId,
3551
+ participants,
3552
+ showSeenBy,
3553
+ typingUsers,
3554
+ hasMore,
3555
+ isLoading,
3556
+ onLoadMore: loadMoreMessages,
3557
+ onDeepLinkClick: handleDeepLink,
3558
+ onMessageVisible: markAsRead,
3559
+ onReply: setReplyTo,
3560
+ onPin: handlePin,
3561
+ onUnpin: handleUnpin,
3562
+ onCopy: handleCopy,
3563
+ onRetry: retryMessage,
3564
+ pinDisabled
3565
+ }
3566
+ ),
3567
+ /* @__PURE__ */ jsxRuntime.jsx(
3568
+ MessageInput,
3569
+ {
3570
+ onSendText: sendMessage,
3571
+ onSendAudio: sendAudioMessage,
3572
+ onSendFile: sendFileMessage,
3573
+ onTyping: sendTyping,
3574
+ replyTo,
3575
+ onCancelReply: () => setReplyTo(null)
3576
+ }
3577
+ )
3578
+ ] }),
3579
+ /* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, onDismiss: () => setToast(null) })
3580
+ ] });
3178
3581
  }
3179
3582
  var panelStyles = {
3180
3583
  container: {
3584
+ position: "relative",
3181
3585
  display: "flex",
3182
3586
  flexDirection: "column",
3183
3587
  height: "100%",
@@ -3244,6 +3648,7 @@ function ExpandIcon({ size = 18, color = "currentColor" }) {
3244
3648
  }
3245
3649
  );
3246
3650
  }
3651
+ var FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
3247
3652
  function CollabPopup({
3248
3653
  orderId,
3249
3654
  patientData,
@@ -3265,6 +3670,8 @@ function CollabPopup({
3265
3670
  const [isMinimized, setIsMinimized] = React4.useState(false);
3266
3671
  const dragOffset = React4.useRef({ x: 0, y: 0 });
3267
3672
  const containerRef = React4.useRef(null);
3673
+ const previouslyFocused = React4.useRef(null);
3674
+ const titleId = React4.useId();
3268
3675
  const handleMouseDown = React4.useCallback(
3269
3676
  (e) => {
3270
3677
  if (!e.target.closest("[data-drag-handle]")) return;
@@ -3279,13 +3686,44 @@ function CollabPopup({
3279
3686
  );
3280
3687
  React4.useEffect(() => {
3281
3688
  if (!isOpen) return;
3689
+ previouslyFocused.current = document.activeElement;
3690
+ const focusFirst = () => {
3691
+ const root = containerRef.current;
3692
+ if (!root) return;
3693
+ const first = root.querySelector(FOCUSABLE_SELECTOR);
3694
+ (first ?? root).focus();
3695
+ };
3696
+ const raf = requestAnimationFrame(focusFirst);
3282
3697
  const handleKey = (e) => {
3283
3698
  if (e.key === "Escape") {
3284
3699
  onClose();
3700
+ return;
3701
+ }
3702
+ if (e.key !== "Tab") return;
3703
+ const root = containerRef.current;
3704
+ if (!root) return;
3705
+ const focusables = Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR));
3706
+ if (focusables.length === 0) {
3707
+ e.preventDefault();
3708
+ return;
3709
+ }
3710
+ const first = focusables[0];
3711
+ const last = focusables[focusables.length - 1];
3712
+ const active = document.activeElement;
3713
+ if (e.shiftKey && active === first) {
3714
+ e.preventDefault();
3715
+ last.focus();
3716
+ } else if (!e.shiftKey && active === last) {
3717
+ e.preventDefault();
3718
+ first.focus();
3285
3719
  }
3286
3720
  };
3287
3721
  window.addEventListener("keydown", handleKey);
3288
- return () => window.removeEventListener("keydown", handleKey);
3722
+ return () => {
3723
+ cancelAnimationFrame(raf);
3724
+ window.removeEventListener("keydown", handleKey);
3725
+ previouslyFocused.current?.focus?.();
3726
+ };
3289
3727
  }, [isOpen, onClose]);
3290
3728
  React4.useEffect(() => {
3291
3729
  if (!isDragging) return;
@@ -3311,8 +3749,12 @@ function CollabPopup({
3311
3749
  {
3312
3750
  ref: containerRef,
3313
3751
  className,
3752
+ role: "dialog",
3753
+ "aria-modal": "true",
3754
+ "aria-labelledby": titleId,
3755
+ tabIndex: -1,
3314
3756
  style: {
3315
- ...styles12.container,
3757
+ ...styles13.container,
3316
3758
  left: position.x,
3317
3759
  top: position.y,
3318
3760
  width,
@@ -3321,14 +3763,14 @@ function CollabPopup({
3321
3763
  },
3322
3764
  onMouseDown: handleMouseDown,
3323
3765
  children: [
3324
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-drag-handle": true, style: styles12.titleBar, children: [
3325
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles12.titleText, children: buildChannelName(patientData) }),
3326
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles12.titleActions, children: [
3766
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-drag-handle": true, style: styles13.titleBar, children: [
3767
+ /* @__PURE__ */ jsxRuntime.jsx("span", { id: titleId, style: styles13.titleText, children: buildChannelName(patientData) }),
3768
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.titleActions, children: [
3327
3769
  /* @__PURE__ */ jsxRuntime.jsx(
3328
3770
  "button",
3329
3771
  {
3330
3772
  onClick: () => setIsMinimized(!isMinimized),
3331
- style: styles12.titleButton,
3773
+ style: styles13.titleButton,
3332
3774
  "aria-label": isMinimized ? "Expand chat" : "Minimize chat",
3333
3775
  title: isMinimized ? "Expand" : "Minimize",
3334
3776
  type: "button",
@@ -3339,7 +3781,7 @@ function CollabPopup({
3339
3781
  "button",
3340
3782
  {
3341
3783
  onClick: onClose,
3342
- style: styles12.titleButton,
3784
+ style: styles13.titleButton,
3343
3785
  "aria-label": "Close chat",
3344
3786
  title: "Close",
3345
3787
  type: "button",
@@ -3348,12 +3790,12 @@ function CollabPopup({
3348
3790
  )
3349
3791
  ] })
3350
3792
  ] }),
3351
- !isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles12.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(CollabPanel, { orderId, patientData, participantIds }) })
3793
+ !isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(CollabPanel, { orderId, patientData, participantIds }) })
3352
3794
  ]
3353
3795
  }
3354
3796
  );
3355
3797
  }
3356
- var styles12 = {
3798
+ var styles13 = {
3357
3799
  container: {
3358
3800
  position: "fixed",
3359
3801
  zIndex: 9999,
@@ -3658,11 +4100,11 @@ function CollabInline({
3658
4100
  containerRef
3659
4101
  } = useInlineCollab({ orderId, patientData, participantIds, messageLimit });
3660
4102
  if (isLoading && !hasConversation) {
3661
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...styles13.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.loadingState, children: "Loading..." }) });
4103
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...styles14.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.loadingState, children: "Loading..." }) });
3662
4104
  }
3663
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, style: { ...styles13.container, ...style }, children: [
3664
- hasConversation && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.preview, children: messages.slice(-messageLimit).map((message) => /* @__PURE__ */ jsxRuntime.jsx(InlineMessageRow, { message }, message.id)) }),
3665
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.error, children: error }),
4105
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, style: { ...styles14.container, ...style }, children: [
4106
+ hasConversation && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.preview, children: messages.slice(-messageLimit).map((message) => /* @__PURE__ */ jsxRuntime.jsx(InlineMessageRow, { message }, message.id)) }),
4107
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.error, children: error }),
3666
4108
  /* @__PURE__ */ jsxRuntime.jsx(
3667
4109
  InlineInputBar,
3668
4110
  {
@@ -3679,12 +4121,12 @@ function CollabInline({
3679
4121
  }
3680
4122
  function InlineMessageRow({ message }) {
3681
4123
  if (message.type === "system") {
3682
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.systemRow, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.systemText, children: message.body }) });
4124
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.systemRow, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.systemText, children: message.body }) });
3683
4125
  }
3684
4126
  if (message.type === "audio" && message.mediaUrl) {
3685
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.messageRow, children: [
4127
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
3686
4128
  /* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
3687
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles13.senderName, children: [
4129
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
3688
4130
  message.senderName,
3689
4131
  ":"
3690
4132
  ] }),
@@ -3692,13 +4134,13 @@ function InlineMessageRow({ message }) {
3692
4134
  ] });
3693
4135
  }
3694
4136
  const preview = renderMessagePreview(message);
3695
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.messageRow, children: [
4137
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
3696
4138
  /* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
3697
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles13.senderName, children: [
4139
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
3698
4140
  message.senderName,
3699
4141
  ":"
3700
4142
  ] }),
3701
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.messageText, children: preview })
4143
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.messageText, children: preview })
3702
4144
  ] });
3703
4145
  }
3704
4146
  function RoleDot({ role }) {
@@ -3708,7 +4150,7 @@ function RoleDot({ role }) {
3708
4150
  physician: "#059669",
3709
4151
  admin: "#dc2626"
3710
4152
  };
3711
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.roleDot, backgroundColor: colors[role] } });
4153
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
3712
4154
  }
3713
4155
  function InlineAudioPlayer({ url, duration }) {
3714
4156
  const audioRef = React4.useRef(null);
@@ -3752,27 +4194,27 @@ function InlineAudioPlayer({ url, duration }) {
3752
4194
  const total = duration ?? 0;
3753
4195
  const remaining = Math.max(0, total - Math.floor(currentTime));
3754
4196
  const displayTime = isPlaying ? remaining : total;
3755
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles13.audioPlayer, children: [
4197
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.audioPlayer, children: [
3756
4198
  /* @__PURE__ */ jsxRuntime.jsx(
3757
4199
  "button",
3758
4200
  {
3759
4201
  onClick: toggle,
3760
- style: styles13.audioButton,
4202
+ style: styles14.audioButton,
3761
4203
  title: isPlaying ? "Pause" : "Play",
3762
4204
  type: "button",
3763
4205
  children: isPlaying ? "\u23F8" : "\u25B6"
3764
4206
  }
3765
4207
  ),
3766
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles13.audioWaveform, children: [
3767
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "40%" } }),
3768
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "80%" } }),
3769
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "60%" } }),
3770
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "90%" } }),
3771
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "50%" } }),
3772
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "70%" } }),
3773
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles13.waveBar, height: "40%" } })
4208
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.audioWaveform, children: [
4209
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "40%" } }),
4210
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "80%" } }),
4211
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "60%" } }),
4212
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "90%" } }),
4213
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "50%" } }),
4214
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "70%" } }),
4215
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "40%" } })
3774
4216
  ] }),
3775
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.audioDuration, children: formatDuration2(displayTime) }),
4217
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.audioDuration, children: formatDuration2(displayTime) }),
3776
4218
  /* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, src: url, preload: "metadata" })
3777
4219
  ] });
3778
4220
  }
@@ -3828,7 +4270,7 @@ function InlineInputBar({
3828
4270
  },
3829
4271
  [handleSend]
3830
4272
  );
3831
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.inputBar, children: [
4273
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.inputBar, children: [
3832
4274
  /* @__PURE__ */ jsxRuntime.jsx(
3833
4275
  "input",
3834
4276
  {
@@ -3839,17 +4281,17 @@ function InlineInputBar({
3839
4281
  onKeyDown: handleKeyDown,
3840
4282
  placeholder,
3841
4283
  disabled: isSending,
3842
- style: styles13.input
4284
+ style: styles14.input
3843
4285
  }
3844
4286
  ),
3845
- unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.unreadBadge, title: `${unreadCount} unread`, children: unreadCount > 99 ? "99+" : unreadCount }),
3846
- isLive && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.liveDot, title: "Live updates active" }),
4287
+ unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.unreadBadge, title: `${unreadCount} unread`, children: unreadCount > 99 ? "99+" : unreadCount }),
4288
+ isLive && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.liveDot, title: "Live updates active" }),
3847
4289
  text.trim() && /* @__PURE__ */ jsxRuntime.jsx(
3848
4290
  "button",
3849
4291
  {
3850
4292
  onClick: handleSend,
3851
4293
  disabled: isSending,
3852
- style: styles13.sendButton,
4294
+ style: styles14.sendButton,
3853
4295
  title: "Send message",
3854
4296
  type: "button",
3855
4297
  children: "\u27A4"
@@ -3859,7 +4301,7 @@ function InlineInputBar({
3859
4301
  "button",
3860
4302
  {
3861
4303
  onClick: onExpand,
3862
- style: styles13.expandButton,
4304
+ style: styles14.expandButton,
3863
4305
  title: "Expand to full chat",
3864
4306
  type: "button",
3865
4307
  children: "\u26F6"
@@ -3867,7 +4309,7 @@ function InlineInputBar({
3867
4309
  )
3868
4310
  ] });
3869
4311
  }
3870
- var styles13 = {
4312
+ var styles14 = {
3871
4313
  container: {
3872
4314
  display: "flex",
3873
4315
  flexDirection: "column",
@@ -4134,24 +4576,24 @@ function ConversationListItem({
4134
4576
  className,
4135
4577
  onClick,
4136
4578
  style: {
4137
- ...styles14.container,
4138
- ...isSelected ? styles14.selected : {},
4139
- ...hasUnread ? styles14.unread : {}
4579
+ ...styles15.container,
4580
+ ...isSelected ? styles15.selected : {},
4581
+ ...hasUnread ? styles15.unread : {}
4140
4582
  },
4141
4583
  type: "button",
4142
4584
  children: [
4143
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.avatarWrapper, children: [
4144
- item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style: styles14.avatar }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.avatarFallback, children: (displayName).charAt(0).toUpperCase() }),
4145
- hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.unreadDot })
4585
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.avatarWrapper, children: [
4586
+ item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style: styles15.avatar }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.avatarFallback, children: (displayName).charAt(0).toUpperCase() }),
4587
+ hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.unreadDot })
4146
4588
  ] }),
4147
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.content, children: [
4148
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.topRow, children: [
4589
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.content, children: [
4590
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.topRow, children: [
4149
4591
  /* @__PURE__ */ jsxRuntime.jsx(
4150
4592
  "span",
4151
4593
  {
4152
4594
  style: {
4153
- ...styles14.name,
4154
- ...hasUnread ? styles14.nameUnread : {}
4595
+ ...styles15.name,
4596
+ ...hasUnread ? styles15.nameUnread : {}
4155
4597
  },
4156
4598
  children: displayName
4157
4599
  }
@@ -4160,25 +4602,25 @@ function ConversationListItem({
4160
4602
  "span",
4161
4603
  {
4162
4604
  style: {
4163
- ...styles14.time,
4164
- ...hasUnread ? styles14.timeUnread : {}
4605
+ ...styles15.time,
4606
+ ...hasUnread ? styles15.timeUnread : {}
4165
4607
  },
4166
4608
  children: formatInboxTimestamp(item.lastActivityAt)
4167
4609
  }
4168
4610
  )
4169
4611
  ] }),
4170
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.bottomRow, children: [
4612
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.bottomRow, children: [
4171
4613
  /* @__PURE__ */ jsxRuntime.jsx(
4172
4614
  "span",
4173
4615
  {
4174
4616
  style: {
4175
- ...styles14.preview,
4176
- ...hasUnread ? styles14.previewUnread : {}
4617
+ ...styles15.preview,
4618
+ ...hasUnread ? styles15.previewUnread : {}
4177
4619
  },
4178
4620
  children: renderLastMessagePreview(item.lastMessage)
4179
4621
  }
4180
4622
  ),
4181
- hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
4623
+ hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
4182
4624
  ] })
4183
4625
  ] })
4184
4626
  ]
@@ -4206,7 +4648,7 @@ function renderLastMessagePreview(message) {
4206
4648
  }
4207
4649
  }
4208
4650
  }
4209
- var styles14 = {
4651
+ var styles15 = {
4210
4652
  container: {
4211
4653
  display: "flex",
4212
4654
  alignItems: "center",
@@ -4353,30 +4795,30 @@ function ConversationList({
4353
4795
  return result;
4354
4796
  }, [conversations, query, showUnreadOnly]);
4355
4797
  const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
4356
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles15.container, children: [
4357
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.header, children: [
4358
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.titleRow, children: [
4359
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles15.title, children: title }),
4360
- totalUnread > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.totalBadge, children: totalUnread })
4798
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles16.container, children: [
4799
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.header, children: [
4800
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.titleRow, children: [
4801
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles16.title, children: title }),
4802
+ totalUnread > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles16.totalBadge, children: totalUnread })
4361
4803
  ] }),
4362
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.searchRow, children: /* @__PURE__ */ jsxRuntime.jsx(
4804
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsxRuntime.jsx(
4363
4805
  "input",
4364
4806
  {
4365
4807
  type: "text",
4366
4808
  value: query,
4367
4809
  onChange: (e) => setQuery(e.target.value),
4368
4810
  placeholder: "Search patients or channels...",
4369
- style: styles15.searchInput
4811
+ style: styles16.searchInput
4370
4812
  }
4371
4813
  ) }),
4372
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.filterRow, children: [
4814
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.filterRow, children: [
4373
4815
  /* @__PURE__ */ jsxRuntime.jsx(
4374
4816
  "button",
4375
4817
  {
4376
4818
  onClick: () => setShowUnreadOnly(false),
4377
4819
  style: {
4378
- ...styles15.filterButton,
4379
- ...!showUnreadOnly ? styles15.filterButtonActive : {}
4820
+ ...styles16.filterButton,
4821
+ ...!showUnreadOnly ? styles16.filterButtonActive : {}
4380
4822
  },
4381
4823
  type: "button",
4382
4824
  children: "All"
@@ -4387,8 +4829,8 @@ function ConversationList({
4387
4829
  {
4388
4830
  onClick: () => setShowUnreadOnly(true),
4389
4831
  style: {
4390
- ...styles15.filterButton,
4391
- ...showUnreadOnly ? styles15.filterButtonActive : {}
4832
+ ...styles16.filterButton,
4833
+ ...showUnreadOnly ? styles16.filterButtonActive : {}
4392
4834
  },
4393
4835
  type: "button",
4394
4836
  children: [
@@ -4399,10 +4841,10 @@ function ConversationList({
4399
4841
  )
4400
4842
  ] })
4401
4843
  ] }),
4402
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.list, children: [
4403
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.state, children: "Loading conversations..." }),
4404
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.errorState, children: error }),
4405
- !isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.state, children: query ? "No matching conversations" : "No conversations yet" }),
4844
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.list, children: [
4845
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.state, children: "Loading conversations..." }),
4846
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.errorState, children: error }),
4847
+ !isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.state, children: query ? "No matching conversations" : "No conversations yet" }),
4406
4848
  filtered.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
4407
4849
  ConversationListItem,
4408
4850
  {
@@ -4415,7 +4857,7 @@ function ConversationList({
4415
4857
  ] })
4416
4858
  ] });
4417
4859
  }
4418
- var styles15 = {
4860
+ var styles16 = {
4419
4861
  container: {
4420
4862
  display: "flex",
4421
4863
  flexDirection: "column",
@@ -4520,8 +4962,8 @@ function CollabInbox({
4520
4962
  setSelectedId(item.id);
4521
4963
  onSelectConversation?.(item);
4522
4964
  };
4523
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...styles16.container, ...style }, children: [
4524
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.sidebar, children: /* @__PURE__ */ jsxRuntime.jsx(
4965
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...styles17.container, ...style }, children: [
4966
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.sidebar, children: /* @__PURE__ */ jsxRuntime.jsx(
4525
4967
  ConversationList,
4526
4968
  {
4527
4969
  conversations,
@@ -4532,13 +4974,13 @@ function CollabInbox({
4532
4974
  title
4533
4975
  }
4534
4976
  ) }),
4535
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.main, children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
4977
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.main, children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
4536
4978
  CollabPanel,
4537
4979
  {
4538
4980
  orderId: selected.orderId,
4539
4981
  patientData: buildPatientData(selected),
4540
4982
  showSeenBy: true,
4541
- style: styles16.panel
4983
+ style: styles17.panel
4542
4984
  },
4543
4985
  selected.id
4544
4986
  ) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { hasAny: conversations.length > 0 }) })
@@ -4552,13 +4994,13 @@ function buildPatientData(item) {
4552
4994
  };
4553
4995
  }
4554
4996
  function EmptyState({ hasAny }) {
4555
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.empty, children: [
4556
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.emptyIcon, children: "\u{1F4AC}" }),
4557
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles16.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
4558
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles16.emptySubtitle, children: hasAny ? "Pick a patient from the list to start collaborating" : "Conversations appear here once you start messaging about a case" })
4997
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles17.empty, children: [
4998
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.emptyIcon, children: "\u{1F4AC}" }),
4999
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles17.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
5000
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: styles17.emptySubtitle, children: hasAny ? "Pick a patient from the list to start collaborating" : "Conversations appear here once you start messaging about a case" })
4559
5001
  ] });
4560
5002
  }
4561
- var styles16 = {
5003
+ var styles17 = {
4562
5004
  container: {
4563
5005
  display: "flex",
4564
5006
  height: "100%",