@natoe/colab 0.1.2 → 0.1.4
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 +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +655 -237
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +655 -237
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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(
|
|
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,
|
|
@@ -1159,7 +1193,7 @@ var styles = {
|
|
|
1159
1193
|
},
|
|
1160
1194
|
patientName: {
|
|
1161
1195
|
fontWeight: 600,
|
|
1162
|
-
fontSize: "
|
|
1196
|
+
fontSize: "17px",
|
|
1163
1197
|
color: "#111827"
|
|
1164
1198
|
},
|
|
1165
1199
|
secondaryRow: {
|
|
@@ -1169,8 +1203,8 @@ var styles = {
|
|
|
1169
1203
|
alignItems: "center"
|
|
1170
1204
|
},
|
|
1171
1205
|
secondary: {
|
|
1172
|
-
fontSize: "
|
|
1173
|
-
color: "#
|
|
1206
|
+
fontSize: "13px",
|
|
1207
|
+
color: "#4b5563"
|
|
1174
1208
|
},
|
|
1175
1209
|
actions: {
|
|
1176
1210
|
display: "flex",
|
|
@@ -1178,8 +1212,9 @@ var styles = {
|
|
|
1178
1212
|
marginTop: "8px"
|
|
1179
1213
|
},
|
|
1180
1214
|
dicomButton: {
|
|
1181
|
-
|
|
1182
|
-
|
|
1215
|
+
minHeight: "40px",
|
|
1216
|
+
padding: "8px 16px",
|
|
1217
|
+
fontSize: "14px",
|
|
1183
1218
|
fontWeight: 500,
|
|
1184
1219
|
color: "#ffffff",
|
|
1185
1220
|
backgroundColor: "#2563eb",
|
|
@@ -1188,8 +1223,9 @@ var styles = {
|
|
|
1188
1223
|
cursor: "pointer"
|
|
1189
1224
|
},
|
|
1190
1225
|
settingsButton: {
|
|
1191
|
-
|
|
1192
|
-
|
|
1226
|
+
minHeight: "40px",
|
|
1227
|
+
padding: "8px 16px",
|
|
1228
|
+
fontSize: "14px",
|
|
1193
1229
|
fontWeight: 500,
|
|
1194
1230
|
color: "#374151",
|
|
1195
1231
|
backgroundColor: "#ffffff",
|
|
@@ -1430,6 +1466,82 @@ var styles4 = {
|
|
|
1430
1466
|
cursor: "pointer"
|
|
1431
1467
|
}
|
|
1432
1468
|
};
|
|
1469
|
+
function FileIcon({ size = 18, color = "currentColor" }) {
|
|
1470
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1471
|
+
"svg",
|
|
1472
|
+
{
|
|
1473
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1474
|
+
width: size,
|
|
1475
|
+
height: size,
|
|
1476
|
+
viewBox: "0 0 24 24",
|
|
1477
|
+
fill: color,
|
|
1478
|
+
"aria-hidden": "true",
|
|
1479
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z" })
|
|
1480
|
+
}
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
function PinIcon({ size = 14, color = "currentColor" }) {
|
|
1484
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1485
|
+
"svg",
|
|
1486
|
+
{
|
|
1487
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1488
|
+
width: size,
|
|
1489
|
+
height: size,
|
|
1490
|
+
viewBox: "0 0 24 24",
|
|
1491
|
+
fill: color,
|
|
1492
|
+
"aria-hidden": "true",
|
|
1493
|
+
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" })
|
|
1494
|
+
}
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
function AlertIcon({ size = 14, color = "currentColor" }) {
|
|
1498
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1499
|
+
"svg",
|
|
1500
|
+
{
|
|
1501
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1502
|
+
width: size,
|
|
1503
|
+
height: size,
|
|
1504
|
+
viewBox: "0 0 24 24",
|
|
1505
|
+
fill: color,
|
|
1506
|
+
"aria-hidden": "true",
|
|
1507
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" })
|
|
1508
|
+
}
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
function Spinner({ size = 16, color = "#6b7280", thickness = 2 }) {
|
|
1512
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1513
|
+
"span",
|
|
1514
|
+
{
|
|
1515
|
+
role: "status",
|
|
1516
|
+
"aria-label": "Loading",
|
|
1517
|
+
style: {
|
|
1518
|
+
display: "inline-block",
|
|
1519
|
+
width: size,
|
|
1520
|
+
height: size,
|
|
1521
|
+
border: `${thickness}px solid ${color}33`,
|
|
1522
|
+
borderTopColor: color,
|
|
1523
|
+
borderRadius: "50%",
|
|
1524
|
+
animation: "natoe-colab-spin 800ms linear infinite",
|
|
1525
|
+
verticalAlign: "middle"
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1530
|
+
if (typeof document !== "undefined") {
|
|
1531
|
+
const existing = document.getElementById("natoe-colab-spin-keyframes");
|
|
1532
|
+
if (!existing) {
|
|
1533
|
+
const style = document.createElement("style");
|
|
1534
|
+
style.id = "natoe-colab-spin-keyframes";
|
|
1535
|
+
style.textContent = `@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }`;
|
|
1536
|
+
document.head.appendChild(style);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
var ROLE_LABELS = {
|
|
1540
|
+
radiologist: "Radiologist",
|
|
1541
|
+
lab: "Imaging Center",
|
|
1542
|
+
physician: "Physician",
|
|
1543
|
+
admin: "Admin"
|
|
1544
|
+
};
|
|
1433
1545
|
function MessageBubble({
|
|
1434
1546
|
message,
|
|
1435
1547
|
isOwn,
|
|
@@ -1442,6 +1554,7 @@ function MessageBubble({
|
|
|
1442
1554
|
onUnpin,
|
|
1443
1555
|
onCopy,
|
|
1444
1556
|
onReplyJumpTo,
|
|
1557
|
+
onRetry,
|
|
1445
1558
|
pinDisabled = false,
|
|
1446
1559
|
className
|
|
1447
1560
|
}) {
|
|
@@ -1469,7 +1582,10 @@ function MessageBubble({
|
|
|
1469
1582
|
...isOwn ? styles5.ownBubble : styles5.otherBubble
|
|
1470
1583
|
},
|
|
1471
1584
|
children: [
|
|
1472
|
-
message.isPinned && /* @__PURE__ */ jsxRuntime.
|
|
1585
|
+
message.isPinned && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.pinnedBadge, children: [
|
|
1586
|
+
/* @__PURE__ */ jsxRuntime.jsx(PinIcon, { size: 12 }),
|
|
1587
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pinned" })
|
|
1588
|
+
] }),
|
|
1473
1589
|
message.replyToSnapshot && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1474
1590
|
ReplyQuoteBlock,
|
|
1475
1591
|
{
|
|
@@ -1488,7 +1604,25 @@ function MessageBubble({
|
|
|
1488
1604
|
message.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
1489
1605
|
message.type === "deep_link" && /* @__PURE__ */ jsxRuntime.jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
1490
1606
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
1491
|
-
|
|
1607
|
+
isOwn && message.status === "sending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
|
|
1608
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 12, color: "rgba(255,255,255,0.85)" }),
|
|
1609
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Sending\u2026" })
|
|
1610
|
+
] }),
|
|
1611
|
+
isOwn && message.status === "failed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
|
|
1612
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { size: 12, color: "#fecaca" }),
|
|
1613
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Not sent" }),
|
|
1614
|
+
onRetry && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1615
|
+
"button",
|
|
1616
|
+
{
|
|
1617
|
+
type: "button",
|
|
1618
|
+
onClick: () => onRetry(message.id),
|
|
1619
|
+
style: styles5.retryButton,
|
|
1620
|
+
"aria-label": "Retry sending message",
|
|
1621
|
+
children: "Retry"
|
|
1622
|
+
}
|
|
1623
|
+
)
|
|
1624
|
+
] }),
|
|
1625
|
+
showSeenBy && isOwn && !message.status && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1492
1626
|
SeenByIndicator,
|
|
1493
1627
|
{
|
|
1494
1628
|
readBy: message.readBy ?? [],
|
|
@@ -1564,7 +1698,7 @@ function ImageContent({ mediaUrl, fileName }) {
|
|
|
1564
1698
|
function FileContent({ mediaUrl, fileName }) {
|
|
1565
1699
|
if (!mediaUrl) return null;
|
|
1566
1700
|
return /* @__PURE__ */ jsxRuntime.jsxs("a", { href: mediaUrl, target: "_blank", rel: "noopener noreferrer", style: styles5.fileLink, children: [
|
|
1567
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1701
|
+
/* @__PURE__ */ jsxRuntime.jsx(FileIcon, { size: 20 }),
|
|
1568
1702
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.fileName, children: fileName || "Download file" })
|
|
1569
1703
|
] });
|
|
1570
1704
|
}
|
|
@@ -1602,7 +1736,7 @@ function RoleBadge({ role }) {
|
|
|
1602
1736
|
physician: "#059669",
|
|
1603
1737
|
admin: "#dc2626"
|
|
1604
1738
|
};
|
|
1605
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: role });
|
|
1739
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: ROLE_LABELS[role] ?? role });
|
|
1606
1740
|
}
|
|
1607
1741
|
function formatTime(iso) {
|
|
1608
1742
|
try {
|
|
@@ -1631,7 +1765,7 @@ var styles5 = {
|
|
|
1631
1765
|
maxWidth: "75%"
|
|
1632
1766
|
},
|
|
1633
1767
|
bubble: {
|
|
1634
|
-
padding: "
|
|
1768
|
+
padding: "10px 14px",
|
|
1635
1769
|
borderRadius: "12px",
|
|
1636
1770
|
wordBreak: "break-word"
|
|
1637
1771
|
},
|
|
@@ -1646,11 +1780,13 @@ var styles5 = {
|
|
|
1646
1780
|
borderBottomLeftRadius: "4px"
|
|
1647
1781
|
},
|
|
1648
1782
|
pinnedBadge: {
|
|
1649
|
-
display: "inline-
|
|
1650
|
-
|
|
1783
|
+
display: "inline-flex",
|
|
1784
|
+
alignItems: "center",
|
|
1785
|
+
gap: "4px",
|
|
1786
|
+
fontSize: "12px",
|
|
1651
1787
|
fontWeight: 600,
|
|
1652
1788
|
marginBottom: "4px",
|
|
1653
|
-
|
|
1789
|
+
color: "#6b7280"
|
|
1654
1790
|
},
|
|
1655
1791
|
senderRow: {
|
|
1656
1792
|
display: "flex",
|
|
@@ -1659,27 +1795,50 @@ var styles5 = {
|
|
|
1659
1795
|
marginBottom: "4px"
|
|
1660
1796
|
},
|
|
1661
1797
|
senderName: {
|
|
1662
|
-
fontSize: "
|
|
1798
|
+
fontSize: "13px",
|
|
1663
1799
|
fontWeight: 600,
|
|
1664
1800
|
color: "#374151"
|
|
1665
1801
|
},
|
|
1666
1802
|
roleBadge: {
|
|
1667
|
-
fontSize: "
|
|
1668
|
-
fontWeight:
|
|
1669
|
-
padding: "
|
|
1803
|
+
fontSize: "11px",
|
|
1804
|
+
fontWeight: 600,
|
|
1805
|
+
padding: "2px 8px",
|
|
1670
1806
|
borderRadius: "4px"
|
|
1671
1807
|
},
|
|
1672
1808
|
textBody: {
|
|
1673
1809
|
margin: 0,
|
|
1674
|
-
fontSize: "
|
|
1675
|
-
lineHeight: "1.
|
|
1810
|
+
fontSize: "15px",
|
|
1811
|
+
lineHeight: "1.45"
|
|
1676
1812
|
},
|
|
1677
1813
|
timestamp: {
|
|
1678
|
-
fontSize: "
|
|
1679
|
-
|
|
1814
|
+
fontSize: "12px",
|
|
1815
|
+
color: "inherit",
|
|
1816
|
+
opacity: 0.8,
|
|
1680
1817
|
marginTop: "4px",
|
|
1681
1818
|
textAlign: "right"
|
|
1682
1819
|
},
|
|
1820
|
+
statusRow: {
|
|
1821
|
+
display: "flex",
|
|
1822
|
+
alignItems: "center",
|
|
1823
|
+
gap: "6px",
|
|
1824
|
+
marginTop: "4px",
|
|
1825
|
+
fontSize: "12px",
|
|
1826
|
+
justifyContent: "flex-end",
|
|
1827
|
+
color: "rgba(255, 255, 255, 0.9)"
|
|
1828
|
+
},
|
|
1829
|
+
statusText: {
|
|
1830
|
+
opacity: 0.9
|
|
1831
|
+
},
|
|
1832
|
+
retryButton: {
|
|
1833
|
+
background: "transparent",
|
|
1834
|
+
border: "none",
|
|
1835
|
+
color: "#ffffff",
|
|
1836
|
+
fontWeight: 600,
|
|
1837
|
+
fontSize: "12px",
|
|
1838
|
+
textDecoration: "underline",
|
|
1839
|
+
cursor: "pointer",
|
|
1840
|
+
padding: "0 2px"
|
|
1841
|
+
},
|
|
1683
1842
|
actionsWrapper: {
|
|
1684
1843
|
position: "absolute",
|
|
1685
1844
|
top: "50%",
|
|
@@ -1715,9 +1874,6 @@ var styles5 = {
|
|
|
1715
1874
|
color: "inherit",
|
|
1716
1875
|
padding: "6px 0"
|
|
1717
1876
|
},
|
|
1718
|
-
fileIcon: {
|
|
1719
|
-
fontSize: "18px"
|
|
1720
|
-
},
|
|
1721
1877
|
fileName: {
|
|
1722
1878
|
fontSize: "13px",
|
|
1723
1879
|
textDecoration: "underline"
|
|
@@ -1752,15 +1908,53 @@ var styles5 = {
|
|
|
1752
1908
|
justifyContent: "center",
|
|
1753
1909
|
alignItems: "center",
|
|
1754
1910
|
gap: "8px",
|
|
1755
|
-
padding: "
|
|
1756
|
-
fontSize: "
|
|
1757
|
-
color: "#
|
|
1911
|
+
padding: "6px 16px",
|
|
1912
|
+
fontSize: "13px",
|
|
1913
|
+
color: "#6b7280"
|
|
1758
1914
|
},
|
|
1759
1915
|
systemTime: {
|
|
1760
|
-
fontSize: "
|
|
1761
|
-
color: "#
|
|
1916
|
+
fontSize: "12px",
|
|
1917
|
+
color: "#9ca3af"
|
|
1762
1918
|
}
|
|
1763
1919
|
};
|
|
1920
|
+
function ChatIllustration({ size = 96 }) {
|
|
1921
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1922
|
+
"svg",
|
|
1923
|
+
{
|
|
1924
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1925
|
+
width: size,
|
|
1926
|
+
height: size,
|
|
1927
|
+
viewBox: "0 0 120 120",
|
|
1928
|
+
fill: "none",
|
|
1929
|
+
"aria-hidden": "true",
|
|
1930
|
+
children: [
|
|
1931
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "60", cy: "60", r: "56", fill: "#eff6ff" }),
|
|
1932
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1933
|
+
"path",
|
|
1934
|
+
{
|
|
1935
|
+
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",
|
|
1936
|
+
fill: "#ffffff",
|
|
1937
|
+
stroke: "#2563eb",
|
|
1938
|
+
strokeWidth: "2.5"
|
|
1939
|
+
}
|
|
1940
|
+
),
|
|
1941
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1942
|
+
"path",
|
|
1943
|
+
{
|
|
1944
|
+
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",
|
|
1945
|
+
fill: "#dbeafe",
|
|
1946
|
+
stroke: "#2563eb",
|
|
1947
|
+
strokeWidth: "2.5"
|
|
1948
|
+
}
|
|
1949
|
+
),
|
|
1950
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "48", cy: "53", r: "2.5", fill: "#2563eb" }),
|
|
1951
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "58", cy: "53", r: "2.5", fill: "#2563eb" }),
|
|
1952
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "68", cy: "68", r: "2.5", fill: "#2563eb" }),
|
|
1953
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "78", cy: "68", r: "2.5", fill: "#2563eb" })
|
|
1954
|
+
]
|
|
1955
|
+
}
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1764
1958
|
|
|
1765
1959
|
// src/core/dateLabels.ts
|
|
1766
1960
|
var SHORT_MONTHS = [
|
|
@@ -1852,6 +2046,7 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1852
2046
|
onPin,
|
|
1853
2047
|
onUnpin,
|
|
1854
2048
|
onCopy,
|
|
2049
|
+
onRetry,
|
|
1855
2050
|
pinDisabled,
|
|
1856
2051
|
className
|
|
1857
2052
|
}, ref) {
|
|
@@ -1916,12 +2111,17 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1916
2111
|
style: styles6.container,
|
|
1917
2112
|
onScroll: handleScroll,
|
|
1918
2113
|
children: [
|
|
1919
|
-
isLoading && /* @__PURE__ */ jsxRuntime.
|
|
2114
|
+
isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.loadingMore, children: [
|
|
2115
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 14 }),
|
|
2116
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading earlier messages\u2026" })
|
|
2117
|
+
] }),
|
|
1920
2118
|
hasMore && !isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onLoadMore, style: styles6.loadMoreButton, type: "button", children: "Load earlier messages" }),
|
|
1921
2119
|
messages.length === 0 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.empty, children: [
|
|
2120
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChatIllustration, { size: 104 }),
|
|
1922
2121
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptyTitle, children: "No messages yet" }),
|
|
1923
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation
|
|
2122
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation \u2014 everyone on this case will see what you write." })
|
|
1924
2123
|
] }),
|
|
2124
|
+
messages.length === 0 && isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.firstLoad, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 20 }) }),
|
|
1925
2125
|
messages.map((message, index) => {
|
|
1926
2126
|
const currentBucket = dayBucketKey(message.insertedAt);
|
|
1927
2127
|
const prevBucket = index === 0 ? null : dayBucketKey(messages[index - 1].insertedAt);
|
|
@@ -1941,6 +2141,7 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1941
2141
|
onPin,
|
|
1942
2142
|
onUnpin,
|
|
1943
2143
|
onCopy,
|
|
2144
|
+
onRetry,
|
|
1944
2145
|
pinDisabled
|
|
1945
2146
|
}
|
|
1946
2147
|
) })
|
|
@@ -1969,20 +2170,30 @@ var styles6 = {
|
|
|
1969
2170
|
paddingBottom: "8px"
|
|
1970
2171
|
},
|
|
1971
2172
|
loadingMore: {
|
|
1972
|
-
|
|
2173
|
+
display: "flex",
|
|
2174
|
+
alignItems: "center",
|
|
2175
|
+
justifyContent: "center",
|
|
2176
|
+
gap: "8px",
|
|
1973
2177
|
padding: "12px",
|
|
1974
|
-
fontSize: "
|
|
1975
|
-
color: "#
|
|
2178
|
+
fontSize: "14px",
|
|
2179
|
+
color: "#6b7280"
|
|
2180
|
+
},
|
|
2181
|
+
firstLoad: {
|
|
2182
|
+
display: "flex",
|
|
2183
|
+
alignItems: "center",
|
|
2184
|
+
justifyContent: "center",
|
|
2185
|
+
padding: "48px 16px"
|
|
1976
2186
|
},
|
|
1977
2187
|
loadMoreButton: {
|
|
1978
2188
|
display: "block",
|
|
1979
2189
|
margin: "0 auto 12px",
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
2190
|
+
minHeight: "36px",
|
|
2191
|
+
padding: "8px 18px",
|
|
2192
|
+
fontSize: "13px",
|
|
2193
|
+
color: "#374151",
|
|
1983
2194
|
backgroundColor: "transparent",
|
|
1984
|
-
border: "1px solid #
|
|
1985
|
-
borderRadius: "
|
|
2195
|
+
border: "1px solid #d1d5db",
|
|
2196
|
+
borderRadius: "18px",
|
|
1986
2197
|
cursor: "pointer"
|
|
1987
2198
|
},
|
|
1988
2199
|
empty: {
|
|
@@ -1991,21 +2202,25 @@ var styles6 = {
|
|
|
1991
2202
|
alignItems: "center",
|
|
1992
2203
|
justifyContent: "center",
|
|
1993
2204
|
padding: "48px 16px",
|
|
1994
|
-
color: "#
|
|
2205
|
+
color: "#6b7280"
|
|
1995
2206
|
},
|
|
1996
2207
|
emptyTitle: {
|
|
1997
|
-
fontSize: "
|
|
1998
|
-
fontWeight:
|
|
1999
|
-
|
|
2208
|
+
fontSize: "16px",
|
|
2209
|
+
fontWeight: 600,
|
|
2210
|
+
color: "#374151",
|
|
2211
|
+
margin: "14px 0 4px"
|
|
2000
2212
|
},
|
|
2001
2213
|
emptySubtitle: {
|
|
2002
|
-
fontSize: "
|
|
2003
|
-
margin: 0
|
|
2214
|
+
fontSize: "14px",
|
|
2215
|
+
margin: 0,
|
|
2216
|
+
maxWidth: "280px",
|
|
2217
|
+
lineHeight: 1.45,
|
|
2218
|
+
textAlign: "center"
|
|
2004
2219
|
},
|
|
2005
2220
|
typingIndicator: {
|
|
2006
2221
|
padding: "4px 16px 8px",
|
|
2007
|
-
fontSize: "
|
|
2008
|
-
color: "#
|
|
2222
|
+
fontSize: "13px",
|
|
2223
|
+
color: "#6b7280",
|
|
2009
2224
|
fontStyle: "italic"
|
|
2010
2225
|
},
|
|
2011
2226
|
dayDivider: {
|
|
@@ -2015,12 +2230,11 @@ var styles6 = {
|
|
|
2015
2230
|
},
|
|
2016
2231
|
dayDividerPill: {
|
|
2017
2232
|
display: "inline-block",
|
|
2018
|
-
padding: "
|
|
2019
|
-
fontSize: "
|
|
2233
|
+
padding: "5px 14px",
|
|
2234
|
+
fontSize: "13px",
|
|
2020
2235
|
fontWeight: 500,
|
|
2021
|
-
color: "#
|
|
2022
|
-
backgroundColor: "#
|
|
2023
|
-
border: "1px solid #e2e8f0",
|
|
2236
|
+
color: "#334155",
|
|
2237
|
+
backgroundColor: "#e2e8f0",
|
|
2024
2238
|
borderRadius: "12px",
|
|
2025
2239
|
letterSpacing: "0.2px"
|
|
2026
2240
|
}
|
|
@@ -2117,6 +2331,48 @@ var styles7 = {
|
|
|
2117
2331
|
flexShrink: 0
|
|
2118
2332
|
}
|
|
2119
2333
|
};
|
|
2334
|
+
function AttachIcon({ size = 20, color = "currentColor" }) {
|
|
2335
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2336
|
+
"svg",
|
|
2337
|
+
{
|
|
2338
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2339
|
+
width: size,
|
|
2340
|
+
height: size,
|
|
2341
|
+
viewBox: "0 0 24 24",
|
|
2342
|
+
fill: color,
|
|
2343
|
+
"aria-hidden": "true",
|
|
2344
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z" })
|
|
2345
|
+
}
|
|
2346
|
+
);
|
|
2347
|
+
}
|
|
2348
|
+
function SendIcon({ size = 20, color = "currentColor" }) {
|
|
2349
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2350
|
+
"svg",
|
|
2351
|
+
{
|
|
2352
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2353
|
+
width: size,
|
|
2354
|
+
height: size,
|
|
2355
|
+
viewBox: "0 0 24 24",
|
|
2356
|
+
fill: color,
|
|
2357
|
+
"aria-hidden": "true",
|
|
2358
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
|
|
2359
|
+
}
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
function CloseIcon({ size = 18, color = "currentColor" }) {
|
|
2363
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2364
|
+
"svg",
|
|
2365
|
+
{
|
|
2366
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2367
|
+
width: size,
|
|
2368
|
+
height: size,
|
|
2369
|
+
viewBox: "0 0 24 24",
|
|
2370
|
+
fill: color,
|
|
2371
|
+
"aria-hidden": "true",
|
|
2372
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
|
|
2373
|
+
}
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2120
2376
|
function MessageInput({
|
|
2121
2377
|
onSendText,
|
|
2122
2378
|
// MIC DISABLED — onSendAudio still accepted but unused.
|
|
@@ -2205,7 +2461,19 @@ function MessageInput({
|
|
|
2205
2461
|
);
|
|
2206
2462
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles8.container, children: [
|
|
2207
2463
|
replyTo && onCancelReply && /* @__PURE__ */ jsxRuntime.jsx(ReplyPreview, { message: replyTo, onCancel: onCancelReply }),
|
|
2208
|
-
fileError && /* @__PURE__ */ jsxRuntime.
|
|
2464
|
+
fileError && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.error, role: "alert", children: [
|
|
2465
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.errorText, children: fileError }),
|
|
2466
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2467
|
+
"button",
|
|
2468
|
+
{
|
|
2469
|
+
type: "button",
|
|
2470
|
+
onClick: () => setFileError(null),
|
|
2471
|
+
"aria-label": "Dismiss error",
|
|
2472
|
+
style: styles8.errorDismiss,
|
|
2473
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { size: 16 })
|
|
2474
|
+
}
|
|
2475
|
+
)
|
|
2476
|
+
] }),
|
|
2209
2477
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.inputBar, children: [
|
|
2210
2478
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2211
2479
|
"button",
|
|
@@ -2213,9 +2481,10 @@ function MessageInput({
|
|
|
2213
2481
|
onClick: () => fileInputRef.current?.click(),
|
|
2214
2482
|
disabled: disabled || isSending,
|
|
2215
2483
|
style: styles8.iconButton,
|
|
2484
|
+
"aria-label": "Attach file",
|
|
2216
2485
|
title: "Attach file",
|
|
2217
2486
|
type: "button",
|
|
2218
|
-
children: "
|
|
2487
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AttachIcon, { size: 22, color: "#374151" })
|
|
2219
2488
|
}
|
|
2220
2489
|
),
|
|
2221
2490
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2248,12 +2517,14 @@ function MessageInput({
|
|
|
2248
2517
|
{
|
|
2249
2518
|
onClick: handleSendText,
|
|
2250
2519
|
disabled: disabled || isSending || !text.trim(),
|
|
2520
|
+
"aria-label": "Send message",
|
|
2521
|
+
title: "Send message",
|
|
2251
2522
|
style: {
|
|
2252
2523
|
...styles8.sendButton,
|
|
2253
2524
|
opacity: text.trim() ? 1 : 0.4
|
|
2254
2525
|
},
|
|
2255
2526
|
type: "button",
|
|
2256
|
-
children: "
|
|
2527
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SendIcon, { size: 20, color: "#ffffff" })
|
|
2257
2528
|
}
|
|
2258
2529
|
)
|
|
2259
2530
|
] })
|
|
@@ -2265,24 +2536,45 @@ var styles8 = {
|
|
|
2265
2536
|
backgroundColor: "#ffffff"
|
|
2266
2537
|
},
|
|
2267
2538
|
error: {
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2539
|
+
display: "flex",
|
|
2540
|
+
alignItems: "center",
|
|
2541
|
+
justifyContent: "space-between",
|
|
2542
|
+
gap: "8px",
|
|
2543
|
+
padding: "8px 12px 8px 16px",
|
|
2544
|
+
fontSize: "13px",
|
|
2545
|
+
color: "#b91c1c",
|
|
2546
|
+
backgroundColor: "#fef2f2",
|
|
2547
|
+
borderTop: "1px solid #fecaca"
|
|
2548
|
+
},
|
|
2549
|
+
errorText: {
|
|
2550
|
+
flex: 1,
|
|
2551
|
+
minWidth: 0
|
|
2552
|
+
},
|
|
2553
|
+
errorDismiss: {
|
|
2554
|
+
width: "28px",
|
|
2555
|
+
height: "28px",
|
|
2556
|
+
display: "flex",
|
|
2557
|
+
alignItems: "center",
|
|
2558
|
+
justifyContent: "center",
|
|
2559
|
+
backgroundColor: "transparent",
|
|
2560
|
+
border: "none",
|
|
2561
|
+
color: "#b91c1c",
|
|
2562
|
+
borderRadius: "4px",
|
|
2563
|
+
cursor: "pointer",
|
|
2564
|
+
flexShrink: 0
|
|
2272
2565
|
},
|
|
2273
2566
|
inputBar: {
|
|
2274
2567
|
display: "flex",
|
|
2275
2568
|
alignItems: "flex-end",
|
|
2276
|
-
gap: "
|
|
2277
|
-
padding: "
|
|
2569
|
+
gap: "6px",
|
|
2570
|
+
padding: "10px 12px"
|
|
2278
2571
|
},
|
|
2279
2572
|
iconButton: {
|
|
2280
|
-
width: "
|
|
2281
|
-
height: "
|
|
2573
|
+
width: "44px",
|
|
2574
|
+
height: "44px",
|
|
2282
2575
|
display: "flex",
|
|
2283
2576
|
alignItems: "center",
|
|
2284
2577
|
justifyContent: "center",
|
|
2285
|
-
fontSize: "18px",
|
|
2286
2578
|
backgroundColor: "transparent",
|
|
2287
2579
|
border: "none",
|
|
2288
2580
|
borderRadius: "50%",
|
|
@@ -2291,23 +2583,23 @@ var styles8 = {
|
|
|
2291
2583
|
},
|
|
2292
2584
|
textarea: {
|
|
2293
2585
|
flex: 1,
|
|
2294
|
-
padding: "
|
|
2295
|
-
fontSize: "
|
|
2296
|
-
lineHeight: "1.
|
|
2297
|
-
border: "1px solid #
|
|
2298
|
-
borderRadius: "
|
|
2586
|
+
padding: "10px 14px",
|
|
2587
|
+
fontSize: "15px",
|
|
2588
|
+
lineHeight: "1.45",
|
|
2589
|
+
border: "1px solid #d1d5db",
|
|
2590
|
+
borderRadius: "22px",
|
|
2299
2591
|
resize: "none",
|
|
2300
2592
|
outline: "none",
|
|
2301
2593
|
fontFamily: "inherit",
|
|
2302
|
-
maxHeight: "120px"
|
|
2594
|
+
maxHeight: "120px",
|
|
2595
|
+
minHeight: "44px"
|
|
2303
2596
|
},
|
|
2304
2597
|
sendButton: {
|
|
2305
|
-
width: "
|
|
2306
|
-
height: "
|
|
2598
|
+
width: "44px",
|
|
2599
|
+
height: "44px",
|
|
2307
2600
|
display: "flex",
|
|
2308
2601
|
alignItems: "center",
|
|
2309
2602
|
justifyContent: "center",
|
|
2310
|
-
fontSize: "18px",
|
|
2311
2603
|
backgroundColor: "#2563eb",
|
|
2312
2604
|
color: "#ffffff",
|
|
2313
2605
|
border: "none",
|
|
@@ -2927,6 +3219,64 @@ var styles11 = {
|
|
|
2927
3219
|
flexShrink: 0
|
|
2928
3220
|
}
|
|
2929
3221
|
};
|
|
3222
|
+
function Toast({ toast, onDismiss, durationMs = 4e3 }) {
|
|
3223
|
+
React4.useEffect(() => {
|
|
3224
|
+
if (!toast) return;
|
|
3225
|
+
const timer = setTimeout(onDismiss, durationMs);
|
|
3226
|
+
return () => clearTimeout(timer);
|
|
3227
|
+
}, [toast, onDismiss, durationMs]);
|
|
3228
|
+
if (!toast) return null;
|
|
3229
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles12.container, role: "status", "aria-live": "polite", children: [
|
|
3230
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles12.message, children: toast.message }),
|
|
3231
|
+
toast.actionLabel && toast.onAction && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3232
|
+
"button",
|
|
3233
|
+
{
|
|
3234
|
+
type: "button",
|
|
3235
|
+
onClick: () => {
|
|
3236
|
+
toast.onAction?.();
|
|
3237
|
+
onDismiss();
|
|
3238
|
+
},
|
|
3239
|
+
style: styles12.action,
|
|
3240
|
+
children: toast.actionLabel
|
|
3241
|
+
}
|
|
3242
|
+
)
|
|
3243
|
+
] });
|
|
3244
|
+
}
|
|
3245
|
+
var styles12 = {
|
|
3246
|
+
container: {
|
|
3247
|
+
position: "absolute",
|
|
3248
|
+
bottom: "76px",
|
|
3249
|
+
left: "50%",
|
|
3250
|
+
transform: "translateX(-50%)",
|
|
3251
|
+
display: "flex",
|
|
3252
|
+
alignItems: "center",
|
|
3253
|
+
gap: "12px",
|
|
3254
|
+
padding: "10px 14px",
|
|
3255
|
+
backgroundColor: "#1e293b",
|
|
3256
|
+
color: "#ffffff",
|
|
3257
|
+
borderRadius: "8px",
|
|
3258
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.18)",
|
|
3259
|
+
fontSize: "14px",
|
|
3260
|
+
maxWidth: "90%",
|
|
3261
|
+
zIndex: 20
|
|
3262
|
+
},
|
|
3263
|
+
message: {
|
|
3264
|
+
whiteSpace: "nowrap",
|
|
3265
|
+
overflow: "hidden",
|
|
3266
|
+
textOverflow: "ellipsis"
|
|
3267
|
+
},
|
|
3268
|
+
action: {
|
|
3269
|
+
background: "transparent",
|
|
3270
|
+
border: "none",
|
|
3271
|
+
color: "#93c5fd",
|
|
3272
|
+
fontWeight: 600,
|
|
3273
|
+
fontSize: "14px",
|
|
3274
|
+
cursor: "pointer",
|
|
3275
|
+
padding: "4px 6px",
|
|
3276
|
+
textTransform: "uppercase",
|
|
3277
|
+
letterSpacing: "0.4px"
|
|
3278
|
+
}
|
|
3279
|
+
};
|
|
2930
3280
|
function CollabPanel({
|
|
2931
3281
|
orderId,
|
|
2932
3282
|
patientData,
|
|
@@ -2937,6 +3287,7 @@ function CollabPanel({
|
|
|
2937
3287
|
}) {
|
|
2938
3288
|
const { config } = useCollab();
|
|
2939
3289
|
const [showSettings, setShowSettings] = React4.useState(false);
|
|
3290
|
+
const [toast, setToast] = React4.useState(null);
|
|
2940
3291
|
const messageListRef = React4.useRef(null);
|
|
2941
3292
|
const {
|
|
2942
3293
|
conversation,
|
|
@@ -2950,6 +3301,7 @@ function CollabPanel({
|
|
|
2950
3301
|
replyTo,
|
|
2951
3302
|
setReplyTo,
|
|
2952
3303
|
sendMessage,
|
|
3304
|
+
retryMessage,
|
|
2953
3305
|
sendAudioMessage,
|
|
2954
3306
|
sendFileMessage,
|
|
2955
3307
|
sendTyping,
|
|
@@ -2974,10 +3326,33 @@ function CollabPanel({
|
|
|
2974
3326
|
try {
|
|
2975
3327
|
if (navigator.clipboard) {
|
|
2976
3328
|
await navigator.clipboard.writeText(text);
|
|
3329
|
+
setToast({ message: "Copied to clipboard" });
|
|
2977
3330
|
}
|
|
2978
3331
|
} catch {
|
|
2979
3332
|
}
|
|
2980
3333
|
};
|
|
3334
|
+
const handlePin = async (messageId) => {
|
|
3335
|
+
try {
|
|
3336
|
+
await pinMessage(messageId);
|
|
3337
|
+
setToast({
|
|
3338
|
+
message: "Pinned",
|
|
3339
|
+
actionLabel: "Undo",
|
|
3340
|
+
onAction: () => {
|
|
3341
|
+
void unpinMessage(messageId);
|
|
3342
|
+
}
|
|
3343
|
+
});
|
|
3344
|
+
} catch {
|
|
3345
|
+
setToast({ message: "Could not pin message" });
|
|
3346
|
+
}
|
|
3347
|
+
};
|
|
3348
|
+
const handleUnpin = async (messageId) => {
|
|
3349
|
+
try {
|
|
3350
|
+
await unpinMessage(messageId);
|
|
3351
|
+
setToast({ message: "Unpinned" });
|
|
3352
|
+
} catch {
|
|
3353
|
+
setToast({ message: "Could not unpin message" });
|
|
3354
|
+
}
|
|
3355
|
+
};
|
|
2981
3356
|
const pinDisabled = pinnedMessages.length >= MAX_PINNED_MESSAGES;
|
|
2982
3357
|
if (error) {
|
|
2983
3358
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyles.errorState, children: [
|
|
@@ -2988,78 +3363,83 @@ function CollabPanel({
|
|
|
2988
3363
|
if (isLoading && !conversation) {
|
|
2989
3364
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: panelStyles.loadingState, children: "Loading conversation..." }) });
|
|
2990
3365
|
}
|
|
2991
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
conversationId: conversation.id,
|
|
2995
|
-
channelName: conversation.name,
|
|
2996
|
-
channelPicture: conversation.picture,
|
|
2997
|
-
participants,
|
|
2998
|
-
currentUserId: config.userId,
|
|
2999
|
-
isAdmin: channelSettings.isAdmin,
|
|
3000
|
-
isUpdating: channelSettings.isUpdating,
|
|
3001
|
-
error: channelSettings.error,
|
|
3002
|
-
onUpdateChannel: channelSettings.updateChannel,
|
|
3003
|
-
onInviteUser: channelSettings.inviteUser,
|
|
3004
|
-
onRemoveUser: channelSettings.removeUser,
|
|
3005
|
-
onLeaveChannel: channelSettings.leaveChannel,
|
|
3006
|
-
onDeleteChannel: channelSettings.deleteChannel,
|
|
3007
|
-
onClose: () => setShowSettings(false)
|
|
3008
|
-
}
|
|
3009
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3010
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3011
|
-
PatientHeader,
|
|
3366
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...panelStyles.container, ...style }, children: [
|
|
3367
|
+
showSettings && conversation ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3368
|
+
ChannelSettings,
|
|
3012
3369
|
{
|
|
3013
|
-
|
|
3370
|
+
conversationId: conversation.id,
|
|
3371
|
+
channelName: conversation.name,
|
|
3372
|
+
channelPicture: conversation.picture,
|
|
3014
3373
|
participants,
|
|
3015
|
-
onOpenDicom: handleOpenDicom,
|
|
3016
|
-
onOpenSettings: () => setShowSettings(true)
|
|
3017
|
-
}
|
|
3018
|
-
),
|
|
3019
|
-
pinnedMessages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3020
|
-
PinnedMessagesBar,
|
|
3021
|
-
{
|
|
3022
|
-
pinnedMessages,
|
|
3023
|
-
onJumpTo: handleJumpToMessage,
|
|
3024
|
-
onUnpin: unpinMessage
|
|
3025
|
-
}
|
|
3026
|
-
),
|
|
3027
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3028
|
-
MessageList,
|
|
3029
|
-
{
|
|
3030
|
-
ref: messageListRef,
|
|
3031
|
-
messages,
|
|
3032
3374
|
currentUserId: config.userId,
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
onPin: pinMessage,
|
|
3043
|
-
onUnpin: unpinMessage,
|
|
3044
|
-
onCopy: handleCopy,
|
|
3045
|
-
pinDisabled
|
|
3046
|
-
}
|
|
3047
|
-
),
|
|
3048
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3049
|
-
MessageInput,
|
|
3050
|
-
{
|
|
3051
|
-
onSendText: sendMessage,
|
|
3052
|
-
onSendAudio: sendAudioMessage,
|
|
3053
|
-
onSendFile: sendFileMessage,
|
|
3054
|
-
onTyping: sendTyping,
|
|
3055
|
-
replyTo,
|
|
3056
|
-
onCancelReply: () => setReplyTo(null)
|
|
3375
|
+
isAdmin: channelSettings.isAdmin,
|
|
3376
|
+
isUpdating: channelSettings.isUpdating,
|
|
3377
|
+
error: channelSettings.error,
|
|
3378
|
+
onUpdateChannel: channelSettings.updateChannel,
|
|
3379
|
+
onInviteUser: channelSettings.inviteUser,
|
|
3380
|
+
onRemoveUser: channelSettings.removeUser,
|
|
3381
|
+
onLeaveChannel: channelSettings.leaveChannel,
|
|
3382
|
+
onDeleteChannel: channelSettings.deleteChannel,
|
|
3383
|
+
onClose: () => setShowSettings(false)
|
|
3057
3384
|
}
|
|
3058
|
-
)
|
|
3059
|
-
|
|
3385
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3386
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3387
|
+
PatientHeader,
|
|
3388
|
+
{
|
|
3389
|
+
patientData,
|
|
3390
|
+
participants,
|
|
3391
|
+
onOpenDicom: handleOpenDicom,
|
|
3392
|
+
onOpenSettings: () => setShowSettings(true)
|
|
3393
|
+
}
|
|
3394
|
+
),
|
|
3395
|
+
pinnedMessages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3396
|
+
PinnedMessagesBar,
|
|
3397
|
+
{
|
|
3398
|
+
pinnedMessages,
|
|
3399
|
+
onJumpTo: handleJumpToMessage,
|
|
3400
|
+
onUnpin: handleUnpin
|
|
3401
|
+
}
|
|
3402
|
+
),
|
|
3403
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3404
|
+
MessageList,
|
|
3405
|
+
{
|
|
3406
|
+
ref: messageListRef,
|
|
3407
|
+
messages,
|
|
3408
|
+
currentUserId: config.userId,
|
|
3409
|
+
participants,
|
|
3410
|
+
showSeenBy,
|
|
3411
|
+
typingUsers,
|
|
3412
|
+
hasMore,
|
|
3413
|
+
isLoading,
|
|
3414
|
+
onLoadMore: loadMoreMessages,
|
|
3415
|
+
onDeepLinkClick: handleDeepLink,
|
|
3416
|
+
onMessageVisible: markAsRead,
|
|
3417
|
+
onReply: setReplyTo,
|
|
3418
|
+
onPin: handlePin,
|
|
3419
|
+
onUnpin: handleUnpin,
|
|
3420
|
+
onCopy: handleCopy,
|
|
3421
|
+
onRetry: retryMessage,
|
|
3422
|
+
pinDisabled
|
|
3423
|
+
}
|
|
3424
|
+
),
|
|
3425
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3426
|
+
MessageInput,
|
|
3427
|
+
{
|
|
3428
|
+
onSendText: sendMessage,
|
|
3429
|
+
onSendAudio: sendAudioMessage,
|
|
3430
|
+
onSendFile: sendFileMessage,
|
|
3431
|
+
onTyping: sendTyping,
|
|
3432
|
+
replyTo,
|
|
3433
|
+
onCancelReply: () => setReplyTo(null)
|
|
3434
|
+
}
|
|
3435
|
+
)
|
|
3436
|
+
] }),
|
|
3437
|
+
/* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, onDismiss: () => setToast(null) })
|
|
3438
|
+
] });
|
|
3060
3439
|
}
|
|
3061
3440
|
var panelStyles = {
|
|
3062
3441
|
container: {
|
|
3442
|
+
position: "relative",
|
|
3063
3443
|
display: "flex",
|
|
3064
3444
|
flexDirection: "column",
|
|
3065
3445
|
height: "100%",
|
|
@@ -3098,6 +3478,34 @@ var panelStyles = {
|
|
|
3098
3478
|
margin: 0
|
|
3099
3479
|
}
|
|
3100
3480
|
};
|
|
3481
|
+
function MinimizeIcon({ size = 18, color = "currentColor" }) {
|
|
3482
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3483
|
+
"svg",
|
|
3484
|
+
{
|
|
3485
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3486
|
+
width: size,
|
|
3487
|
+
height: size,
|
|
3488
|
+
viewBox: "0 0 24 24",
|
|
3489
|
+
fill: color,
|
|
3490
|
+
"aria-hidden": "true",
|
|
3491
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 19h12v2H6z" })
|
|
3492
|
+
}
|
|
3493
|
+
);
|
|
3494
|
+
}
|
|
3495
|
+
function ExpandIcon({ size = 18, color = "currentColor" }) {
|
|
3496
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3497
|
+
"svg",
|
|
3498
|
+
{
|
|
3499
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3500
|
+
width: size,
|
|
3501
|
+
height: size,
|
|
3502
|
+
viewBox: "0 0 24 24",
|
|
3503
|
+
fill: color,
|
|
3504
|
+
"aria-hidden": "true",
|
|
3505
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 4h16v16H4V4zm2 4v10h12V8H6z" })
|
|
3506
|
+
}
|
|
3507
|
+
);
|
|
3508
|
+
}
|
|
3101
3509
|
function CollabPopup({
|
|
3102
3510
|
orderId,
|
|
3103
3511
|
patientData,
|
|
@@ -3146,7 +3554,7 @@ function CollabPopup({
|
|
|
3146
3554
|
const handleMouseMove = (e) => {
|
|
3147
3555
|
setPosition({
|
|
3148
3556
|
x: Math.max(0, Math.min(e.clientX - dragOffset.current.x, window.innerWidth - width)),
|
|
3149
|
-
y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ?
|
|
3557
|
+
y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ? 52 : height)))
|
|
3150
3558
|
});
|
|
3151
3559
|
};
|
|
3152
3560
|
const handleMouseUp = () => {
|
|
@@ -3166,37 +3574,48 @@ function CollabPopup({
|
|
|
3166
3574
|
ref: containerRef,
|
|
3167
3575
|
className,
|
|
3168
3576
|
style: {
|
|
3169
|
-
...
|
|
3577
|
+
...styles13.container,
|
|
3170
3578
|
left: position.x,
|
|
3171
3579
|
top: position.y,
|
|
3172
3580
|
width,
|
|
3173
|
-
height: isMinimized ?
|
|
3581
|
+
height: isMinimized ? 52 : height,
|
|
3174
3582
|
cursor: isDragging ? "grabbing" : "default"
|
|
3175
3583
|
},
|
|
3176
3584
|
onMouseDown: handleMouseDown,
|
|
3177
3585
|
children: [
|
|
3178
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-drag-handle": true, style:
|
|
3179
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3180
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3586
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-drag-handle": true, style: styles13.titleBar, children: [
|
|
3587
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.titleText, children: buildChannelName(patientData) }),
|
|
3588
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.titleActions, children: [
|
|
3181
3589
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3182
3590
|
"button",
|
|
3183
3591
|
{
|
|
3184
3592
|
onClick: () => setIsMinimized(!isMinimized),
|
|
3185
|
-
style:
|
|
3593
|
+
style: styles13.titleButton,
|
|
3594
|
+
"aria-label": isMinimized ? "Expand chat" : "Minimize chat",
|
|
3186
3595
|
title: isMinimized ? "Expand" : "Minimize",
|
|
3187
3596
|
type: "button",
|
|
3188
|
-
children: isMinimized ? "
|
|
3597
|
+
children: isMinimized ? /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, { size: 16, color: "#cbd5e1" }) : /* @__PURE__ */ jsxRuntime.jsx(MinimizeIcon, { size: 16, color: "#cbd5e1" })
|
|
3189
3598
|
}
|
|
3190
3599
|
),
|
|
3191
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3600
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3601
|
+
"button",
|
|
3602
|
+
{
|
|
3603
|
+
onClick: onClose,
|
|
3604
|
+
style: styles13.titleButton,
|
|
3605
|
+
"aria-label": "Close chat",
|
|
3606
|
+
title: "Close",
|
|
3607
|
+
type: "button",
|
|
3608
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { size: 16, color: "#cbd5e1" })
|
|
3609
|
+
}
|
|
3610
|
+
)
|
|
3192
3611
|
] })
|
|
3193
3612
|
] }),
|
|
3194
|
-
!isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3613
|
+
!isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(CollabPanel, { orderId, patientData, participantIds }) })
|
|
3195
3614
|
]
|
|
3196
3615
|
}
|
|
3197
3616
|
);
|
|
3198
3617
|
}
|
|
3199
|
-
var
|
|
3618
|
+
var styles13 = {
|
|
3200
3619
|
container: {
|
|
3201
3620
|
position: "fixed",
|
|
3202
3621
|
zIndex: 9999,
|
|
@@ -3213,15 +3632,15 @@ var styles12 = {
|
|
|
3213
3632
|
display: "flex",
|
|
3214
3633
|
justifyContent: "space-between",
|
|
3215
3634
|
alignItems: "center",
|
|
3216
|
-
padding: "0
|
|
3217
|
-
height: "
|
|
3635
|
+
padding: "0 8px 0 14px",
|
|
3636
|
+
height: "52px",
|
|
3218
3637
|
backgroundColor: "#1e293b",
|
|
3219
3638
|
cursor: "grab",
|
|
3220
3639
|
userSelect: "none",
|
|
3221
3640
|
flexShrink: 0
|
|
3222
3641
|
},
|
|
3223
3642
|
titleText: {
|
|
3224
|
-
fontSize: "
|
|
3643
|
+
fontSize: "15px",
|
|
3225
3644
|
fontWeight: 500,
|
|
3226
3645
|
color: "#ffffff",
|
|
3227
3646
|
overflow: "hidden",
|
|
@@ -3234,17 +3653,16 @@ var styles12 = {
|
|
|
3234
3653
|
flexShrink: 0
|
|
3235
3654
|
},
|
|
3236
3655
|
titleButton: {
|
|
3237
|
-
width: "
|
|
3238
|
-
height: "
|
|
3656
|
+
width: "40px",
|
|
3657
|
+
height: "40px",
|
|
3239
3658
|
display: "flex",
|
|
3240
3659
|
alignItems: "center",
|
|
3241
3660
|
justifyContent: "center",
|
|
3242
3661
|
backgroundColor: "transparent",
|
|
3243
3662
|
border: "none",
|
|
3244
|
-
borderRadius: "
|
|
3663
|
+
borderRadius: "6px",
|
|
3245
3664
|
cursor: "pointer",
|
|
3246
|
-
|
|
3247
|
-
color: "#94a3b8"
|
|
3665
|
+
color: "#cbd5e1"
|
|
3248
3666
|
},
|
|
3249
3667
|
panelWrapper: {
|
|
3250
3668
|
flex: 1,
|
|
@@ -3502,11 +3920,11 @@ function CollabInline({
|
|
|
3502
3920
|
containerRef
|
|
3503
3921
|
} = useInlineCollab({ orderId, patientData, participantIds, messageLimit });
|
|
3504
3922
|
if (isLoading && !hasConversation) {
|
|
3505
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...
|
|
3923
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...styles14.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.loadingState, children: "Loading..." }) });
|
|
3506
3924
|
}
|
|
3507
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, style: { ...
|
|
3508
|
-
hasConversation && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3509
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3925
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, style: { ...styles14.container, ...style }, children: [
|
|
3926
|
+
hasConversation && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.preview, children: messages.slice(-messageLimit).map((message) => /* @__PURE__ */ jsxRuntime.jsx(InlineMessageRow, { message }, message.id)) }),
|
|
3927
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.error, children: error }),
|
|
3510
3928
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3511
3929
|
InlineInputBar,
|
|
3512
3930
|
{
|
|
@@ -3523,12 +3941,12 @@ function CollabInline({
|
|
|
3523
3941
|
}
|
|
3524
3942
|
function InlineMessageRow({ message }) {
|
|
3525
3943
|
if (message.type === "system") {
|
|
3526
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3944
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles14.systemRow, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.systemText, children: message.body }) });
|
|
3527
3945
|
}
|
|
3528
3946
|
if (message.type === "audio" && message.mediaUrl) {
|
|
3529
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3947
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
|
|
3530
3948
|
/* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
|
|
3531
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3949
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
|
|
3532
3950
|
message.senderName,
|
|
3533
3951
|
":"
|
|
3534
3952
|
] }),
|
|
@@ -3536,13 +3954,13 @@ function InlineMessageRow({ message }) {
|
|
|
3536
3954
|
] });
|
|
3537
3955
|
}
|
|
3538
3956
|
const preview = renderMessagePreview(message);
|
|
3539
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3957
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
|
|
3540
3958
|
/* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
|
|
3541
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3959
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
|
|
3542
3960
|
message.senderName,
|
|
3543
3961
|
":"
|
|
3544
3962
|
] }),
|
|
3545
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3963
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.messageText, children: preview })
|
|
3546
3964
|
] });
|
|
3547
3965
|
}
|
|
3548
3966
|
function RoleDot({ role }) {
|
|
@@ -3552,7 +3970,7 @@ function RoleDot({ role }) {
|
|
|
3552
3970
|
physician: "#059669",
|
|
3553
3971
|
admin: "#dc2626"
|
|
3554
3972
|
};
|
|
3555
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3973
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
|
|
3556
3974
|
}
|
|
3557
3975
|
function InlineAudioPlayer({ url, duration }) {
|
|
3558
3976
|
const audioRef = React4.useRef(null);
|
|
@@ -3596,27 +4014,27 @@ function InlineAudioPlayer({ url, duration }) {
|
|
|
3596
4014
|
const total = duration ?? 0;
|
|
3597
4015
|
const remaining = Math.max(0, total - Math.floor(currentTime));
|
|
3598
4016
|
const displayTime = isPlaying ? remaining : total;
|
|
3599
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
4017
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.audioPlayer, children: [
|
|
3600
4018
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3601
4019
|
"button",
|
|
3602
4020
|
{
|
|
3603
4021
|
onClick: toggle,
|
|
3604
|
-
style:
|
|
4022
|
+
style: styles14.audioButton,
|
|
3605
4023
|
title: isPlaying ? "Pause" : "Play",
|
|
3606
4024
|
type: "button",
|
|
3607
4025
|
children: isPlaying ? "\u23F8" : "\u25B6"
|
|
3608
4026
|
}
|
|
3609
4027
|
),
|
|
3610
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3611
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3612
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3613
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3614
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3615
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3616
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3617
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
4028
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.audioWaveform, children: [
|
|
4029
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "40%" } }),
|
|
4030
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "80%" } }),
|
|
4031
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "60%" } }),
|
|
4032
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "90%" } }),
|
|
4033
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "50%" } }),
|
|
4034
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "70%" } }),
|
|
4035
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.waveBar, height: "40%" } })
|
|
3618
4036
|
] }),
|
|
3619
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4037
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.audioDuration, children: formatDuration2(displayTime) }),
|
|
3620
4038
|
/* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, src: url, preload: "metadata" })
|
|
3621
4039
|
] });
|
|
3622
4040
|
}
|
|
@@ -3672,7 +4090,7 @@ function InlineInputBar({
|
|
|
3672
4090
|
},
|
|
3673
4091
|
[handleSend]
|
|
3674
4092
|
);
|
|
3675
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4093
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.inputBar, children: [
|
|
3676
4094
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3677
4095
|
"input",
|
|
3678
4096
|
{
|
|
@@ -3683,17 +4101,17 @@ function InlineInputBar({
|
|
|
3683
4101
|
onKeyDown: handleKeyDown,
|
|
3684
4102
|
placeholder,
|
|
3685
4103
|
disabled: isSending,
|
|
3686
|
-
style:
|
|
4104
|
+
style: styles14.input
|
|
3687
4105
|
}
|
|
3688
4106
|
),
|
|
3689
|
-
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3690
|
-
isLive && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4107
|
+
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.unreadBadge, title: `${unreadCount} unread`, children: unreadCount > 99 ? "99+" : unreadCount }),
|
|
4108
|
+
isLive && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.liveDot, title: "Live updates active" }),
|
|
3691
4109
|
text.trim() && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3692
4110
|
"button",
|
|
3693
4111
|
{
|
|
3694
4112
|
onClick: handleSend,
|
|
3695
4113
|
disabled: isSending,
|
|
3696
|
-
style:
|
|
4114
|
+
style: styles14.sendButton,
|
|
3697
4115
|
title: "Send message",
|
|
3698
4116
|
type: "button",
|
|
3699
4117
|
children: "\u27A4"
|
|
@@ -3703,7 +4121,7 @@ function InlineInputBar({
|
|
|
3703
4121
|
"button",
|
|
3704
4122
|
{
|
|
3705
4123
|
onClick: onExpand,
|
|
3706
|
-
style:
|
|
4124
|
+
style: styles14.expandButton,
|
|
3707
4125
|
title: "Expand to full chat",
|
|
3708
4126
|
type: "button",
|
|
3709
4127
|
children: "\u26F6"
|
|
@@ -3711,7 +4129,7 @@ function InlineInputBar({
|
|
|
3711
4129
|
)
|
|
3712
4130
|
] });
|
|
3713
4131
|
}
|
|
3714
|
-
var
|
|
4132
|
+
var styles14 = {
|
|
3715
4133
|
container: {
|
|
3716
4134
|
display: "flex",
|
|
3717
4135
|
flexDirection: "column",
|
|
@@ -3978,24 +4396,24 @@ function ConversationListItem({
|
|
|
3978
4396
|
className,
|
|
3979
4397
|
onClick,
|
|
3980
4398
|
style: {
|
|
3981
|
-
...
|
|
3982
|
-
...isSelected ?
|
|
3983
|
-
...hasUnread ?
|
|
4399
|
+
...styles15.container,
|
|
4400
|
+
...isSelected ? styles15.selected : {},
|
|
4401
|
+
...hasUnread ? styles15.unread : {}
|
|
3984
4402
|
},
|
|
3985
4403
|
type: "button",
|
|
3986
4404
|
children: [
|
|
3987
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3988
|
-
item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style:
|
|
3989
|
-
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.avatarWrapper, children: [
|
|
4406
|
+
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() }),
|
|
4407
|
+
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.unreadDot })
|
|
3990
4408
|
] }),
|
|
3991
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3992
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4409
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.content, children: [
|
|
4410
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.topRow, children: [
|
|
3993
4411
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3994
4412
|
"span",
|
|
3995
4413
|
{
|
|
3996
4414
|
style: {
|
|
3997
|
-
...
|
|
3998
|
-
...hasUnread ?
|
|
4415
|
+
...styles15.name,
|
|
4416
|
+
...hasUnread ? styles15.nameUnread : {}
|
|
3999
4417
|
},
|
|
4000
4418
|
children: displayName
|
|
4001
4419
|
}
|
|
@@ -4004,25 +4422,25 @@ function ConversationListItem({
|
|
|
4004
4422
|
"span",
|
|
4005
4423
|
{
|
|
4006
4424
|
style: {
|
|
4007
|
-
...
|
|
4008
|
-
...hasUnread ?
|
|
4425
|
+
...styles15.time,
|
|
4426
|
+
...hasUnread ? styles15.timeUnread : {}
|
|
4009
4427
|
},
|
|
4010
4428
|
children: formatInboxTimestamp(item.lastActivityAt)
|
|
4011
4429
|
}
|
|
4012
4430
|
)
|
|
4013
4431
|
] }),
|
|
4014
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4432
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.bottomRow, children: [
|
|
4015
4433
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4016
4434
|
"span",
|
|
4017
4435
|
{
|
|
4018
4436
|
style: {
|
|
4019
|
-
...
|
|
4020
|
-
...hasUnread ?
|
|
4437
|
+
...styles15.preview,
|
|
4438
|
+
...hasUnread ? styles15.previewUnread : {}
|
|
4021
4439
|
},
|
|
4022
4440
|
children: renderLastMessagePreview(item.lastMessage)
|
|
4023
4441
|
}
|
|
4024
4442
|
),
|
|
4025
|
-
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4443
|
+
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
4026
4444
|
] })
|
|
4027
4445
|
] })
|
|
4028
4446
|
]
|
|
@@ -4050,7 +4468,7 @@ function renderLastMessagePreview(message) {
|
|
|
4050
4468
|
}
|
|
4051
4469
|
}
|
|
4052
4470
|
}
|
|
4053
|
-
var
|
|
4471
|
+
var styles15 = {
|
|
4054
4472
|
container: {
|
|
4055
4473
|
display: "flex",
|
|
4056
4474
|
alignItems: "center",
|
|
@@ -4115,7 +4533,7 @@ var styles14 = {
|
|
|
4115
4533
|
gap: "8px"
|
|
4116
4534
|
},
|
|
4117
4535
|
name: {
|
|
4118
|
-
fontSize: "
|
|
4536
|
+
fontSize: "15px",
|
|
4119
4537
|
fontWeight: 500,
|
|
4120
4538
|
color: "#111827",
|
|
4121
4539
|
overflow: "hidden",
|
|
@@ -4128,8 +4546,8 @@ var styles14 = {
|
|
|
4128
4546
|
fontWeight: 700
|
|
4129
4547
|
},
|
|
4130
4548
|
time: {
|
|
4131
|
-
fontSize: "
|
|
4132
|
-
color: "#
|
|
4549
|
+
fontSize: "12px",
|
|
4550
|
+
color: "#6b7280",
|
|
4133
4551
|
flexShrink: 0
|
|
4134
4552
|
},
|
|
4135
4553
|
timeUnread: {
|
|
@@ -4143,8 +4561,8 @@ var styles14 = {
|
|
|
4143
4561
|
gap: "8px"
|
|
4144
4562
|
},
|
|
4145
4563
|
preview: {
|
|
4146
|
-
fontSize: "
|
|
4147
|
-
color: "#
|
|
4564
|
+
fontSize: "14px",
|
|
4565
|
+
color: "#4b5563",
|
|
4148
4566
|
overflow: "hidden",
|
|
4149
4567
|
textOverflow: "ellipsis",
|
|
4150
4568
|
whiteSpace: "nowrap",
|
|
@@ -4197,30 +4615,30 @@ function ConversationList({
|
|
|
4197
4615
|
return result;
|
|
4198
4616
|
}, [conversations, query, showUnreadOnly]);
|
|
4199
4617
|
const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
|
|
4200
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style:
|
|
4201
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4202
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4203
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { style:
|
|
4204
|
-
totalUnread > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4618
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles16.container, children: [
|
|
4619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.header, children: [
|
|
4620
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.titleRow, children: [
|
|
4621
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles16.title, children: title }),
|
|
4622
|
+
totalUnread > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles16.totalBadge, children: totalUnread })
|
|
4205
4623
|
] }),
|
|
4206
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4624
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4207
4625
|
"input",
|
|
4208
4626
|
{
|
|
4209
4627
|
type: "text",
|
|
4210
4628
|
value: query,
|
|
4211
4629
|
onChange: (e) => setQuery(e.target.value),
|
|
4212
4630
|
placeholder: "Search patients or channels...",
|
|
4213
|
-
style:
|
|
4631
|
+
style: styles16.searchInput
|
|
4214
4632
|
}
|
|
4215
4633
|
) }),
|
|
4216
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4634
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.filterRow, children: [
|
|
4217
4635
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4218
4636
|
"button",
|
|
4219
4637
|
{
|
|
4220
4638
|
onClick: () => setShowUnreadOnly(false),
|
|
4221
4639
|
style: {
|
|
4222
|
-
...
|
|
4223
|
-
...!showUnreadOnly ?
|
|
4640
|
+
...styles16.filterButton,
|
|
4641
|
+
...!showUnreadOnly ? styles16.filterButtonActive : {}
|
|
4224
4642
|
},
|
|
4225
4643
|
type: "button",
|
|
4226
4644
|
children: "All"
|
|
@@ -4231,8 +4649,8 @@ function ConversationList({
|
|
|
4231
4649
|
{
|
|
4232
4650
|
onClick: () => setShowUnreadOnly(true),
|
|
4233
4651
|
style: {
|
|
4234
|
-
...
|
|
4235
|
-
...showUnreadOnly ?
|
|
4652
|
+
...styles16.filterButton,
|
|
4653
|
+
...showUnreadOnly ? styles16.filterButtonActive : {}
|
|
4236
4654
|
},
|
|
4237
4655
|
type: "button",
|
|
4238
4656
|
children: [
|
|
@@ -4243,10 +4661,10 @@ function ConversationList({
|
|
|
4243
4661
|
)
|
|
4244
4662
|
] })
|
|
4245
4663
|
] }),
|
|
4246
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4247
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4248
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4249
|
-
!isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4664
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.list, children: [
|
|
4665
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.state, children: "Loading conversations..." }),
|
|
4666
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.errorState, children: error }),
|
|
4667
|
+
!isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.state, children: query ? "No matching conversations" : "No conversations yet" }),
|
|
4250
4668
|
filtered.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4251
4669
|
ConversationListItem,
|
|
4252
4670
|
{
|
|
@@ -4259,7 +4677,7 @@ function ConversationList({
|
|
|
4259
4677
|
] })
|
|
4260
4678
|
] });
|
|
4261
4679
|
}
|
|
4262
|
-
var
|
|
4680
|
+
var styles16 = {
|
|
4263
4681
|
container: {
|
|
4264
4682
|
display: "flex",
|
|
4265
4683
|
flexDirection: "column",
|
|
@@ -4364,8 +4782,8 @@ function CollabInbox({
|
|
|
4364
4782
|
setSelectedId(item.id);
|
|
4365
4783
|
onSelectConversation?.(item);
|
|
4366
4784
|
};
|
|
4367
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...
|
|
4368
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4785
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...styles17.container, ...style }, children: [
|
|
4786
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.sidebar, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4369
4787
|
ConversationList,
|
|
4370
4788
|
{
|
|
4371
4789
|
conversations,
|
|
@@ -4376,13 +4794,13 @@ function CollabInbox({
|
|
|
4376
4794
|
title
|
|
4377
4795
|
}
|
|
4378
4796
|
) }),
|
|
4379
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4797
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.main, children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4380
4798
|
CollabPanel,
|
|
4381
4799
|
{
|
|
4382
4800
|
orderId: selected.orderId,
|
|
4383
4801
|
patientData: buildPatientData(selected),
|
|
4384
4802
|
showSeenBy: true,
|
|
4385
|
-
style:
|
|
4803
|
+
style: styles17.panel
|
|
4386
4804
|
},
|
|
4387
4805
|
selected.id
|
|
4388
4806
|
) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { hasAny: conversations.length > 0 }) })
|
|
@@ -4396,13 +4814,13 @@ function buildPatientData(item) {
|
|
|
4396
4814
|
};
|
|
4397
4815
|
}
|
|
4398
4816
|
function EmptyState({ hasAny }) {
|
|
4399
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4400
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4401
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { style:
|
|
4402
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
4817
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles17.empty, children: [
|
|
4818
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.emptyIcon, children: "\u{1F4AC}" }),
|
|
4819
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles17.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
|
|
4820
|
+
/* @__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" })
|
|
4403
4821
|
] });
|
|
4404
4822
|
}
|
|
4405
|
-
var
|
|
4823
|
+
var styles17 = {
|
|
4406
4824
|
container: {
|
|
4407
4825
|
display: "flex",
|
|
4408
4826
|
height: "100%",
|