@natoe/colab 0.1.3 → 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 +414 -152
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +414 -152
- 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,
|
|
@@ -1460,6 +1494,48 @@ function PinIcon({ size = 14, color = "currentColor" }) {
|
|
|
1460
1494
|
}
|
|
1461
1495
|
);
|
|
1462
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
|
+
}
|
|
1463
1539
|
var ROLE_LABELS = {
|
|
1464
1540
|
radiologist: "Radiologist",
|
|
1465
1541
|
lab: "Imaging Center",
|
|
@@ -1478,6 +1554,7 @@ function MessageBubble({
|
|
|
1478
1554
|
onUnpin,
|
|
1479
1555
|
onCopy,
|
|
1480
1556
|
onReplyJumpTo,
|
|
1557
|
+
onRetry,
|
|
1481
1558
|
pinDisabled = false,
|
|
1482
1559
|
className
|
|
1483
1560
|
}) {
|
|
@@ -1527,7 +1604,25 @@ function MessageBubble({
|
|
|
1527
1604
|
message.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
1528
1605
|
message.type === "deep_link" && /* @__PURE__ */ jsxRuntime.jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
1529
1606
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
1530
|
-
|
|
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(
|
|
1531
1626
|
SeenByIndicator,
|
|
1532
1627
|
{
|
|
1533
1628
|
readBy: message.readBy ?? [],
|
|
@@ -1722,6 +1817,28 @@ var styles5 = {
|
|
|
1722
1817
|
marginTop: "4px",
|
|
1723
1818
|
textAlign: "right"
|
|
1724
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
|
+
},
|
|
1725
1842
|
actionsWrapper: {
|
|
1726
1843
|
position: "absolute",
|
|
1727
1844
|
top: "50%",
|
|
@@ -1800,6 +1917,44 @@ var styles5 = {
|
|
|
1800
1917
|
color: "#9ca3af"
|
|
1801
1918
|
}
|
|
1802
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
|
+
}
|
|
1803
1958
|
|
|
1804
1959
|
// src/core/dateLabels.ts
|
|
1805
1960
|
var SHORT_MONTHS = [
|
|
@@ -1891,6 +2046,7 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1891
2046
|
onPin,
|
|
1892
2047
|
onUnpin,
|
|
1893
2048
|
onCopy,
|
|
2049
|
+
onRetry,
|
|
1894
2050
|
pinDisabled,
|
|
1895
2051
|
className
|
|
1896
2052
|
}, ref) {
|
|
@@ -1955,12 +2111,17 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1955
2111
|
style: styles6.container,
|
|
1956
2112
|
onScroll: handleScroll,
|
|
1957
2113
|
children: [
|
|
1958
|
-
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
|
+
] }),
|
|
1959
2118
|
hasMore && !isLoading && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onLoadMore, style: styles6.loadMoreButton, type: "button", children: "Load earlier messages" }),
|
|
1960
2119
|
messages.length === 0 && !isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.empty, children: [
|
|
2120
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChatIllustration, { size: 104 }),
|
|
1961
2121
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.emptyTitle, children: "No messages yet" }),
|
|
1962
|
-
/* @__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." })
|
|
1963
2123
|
] }),
|
|
2124
|
+
messages.length === 0 && isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.firstLoad, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 20 }) }),
|
|
1964
2125
|
messages.map((message, index) => {
|
|
1965
2126
|
const currentBucket = dayBucketKey(message.insertedAt);
|
|
1966
2127
|
const prevBucket = index === 0 ? null : dayBucketKey(messages[index - 1].insertedAt);
|
|
@@ -1980,6 +2141,7 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
1980
2141
|
onPin,
|
|
1981
2142
|
onUnpin,
|
|
1982
2143
|
onCopy,
|
|
2144
|
+
onRetry,
|
|
1983
2145
|
pinDisabled
|
|
1984
2146
|
}
|
|
1985
2147
|
) })
|
|
@@ -2008,11 +2170,20 @@ var styles6 = {
|
|
|
2008
2170
|
paddingBottom: "8px"
|
|
2009
2171
|
},
|
|
2010
2172
|
loadingMore: {
|
|
2011
|
-
|
|
2173
|
+
display: "flex",
|
|
2174
|
+
alignItems: "center",
|
|
2175
|
+
justifyContent: "center",
|
|
2176
|
+
gap: "8px",
|
|
2012
2177
|
padding: "12px",
|
|
2013
2178
|
fontSize: "14px",
|
|
2014
2179
|
color: "#6b7280"
|
|
2015
2180
|
},
|
|
2181
|
+
firstLoad: {
|
|
2182
|
+
display: "flex",
|
|
2183
|
+
alignItems: "center",
|
|
2184
|
+
justifyContent: "center",
|
|
2185
|
+
padding: "48px 16px"
|
|
2186
|
+
},
|
|
2016
2187
|
loadMoreButton: {
|
|
2017
2188
|
display: "block",
|
|
2018
2189
|
margin: "0 auto 12px",
|
|
@@ -2037,11 +2208,14 @@ var styles6 = {
|
|
|
2037
2208
|
fontSize: "16px",
|
|
2038
2209
|
fontWeight: 600,
|
|
2039
2210
|
color: "#374151",
|
|
2040
|
-
margin: "
|
|
2211
|
+
margin: "14px 0 4px"
|
|
2041
2212
|
},
|
|
2042
2213
|
emptySubtitle: {
|
|
2043
2214
|
fontSize: "14px",
|
|
2044
|
-
margin: 0
|
|
2215
|
+
margin: 0,
|
|
2216
|
+
maxWidth: "280px",
|
|
2217
|
+
lineHeight: 1.45,
|
|
2218
|
+
textAlign: "center"
|
|
2045
2219
|
},
|
|
2046
2220
|
typingIndicator: {
|
|
2047
2221
|
padding: "4px 16px 8px",
|
|
@@ -3045,6 +3219,64 @@ var styles11 = {
|
|
|
3045
3219
|
flexShrink: 0
|
|
3046
3220
|
}
|
|
3047
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
|
+
};
|
|
3048
3280
|
function CollabPanel({
|
|
3049
3281
|
orderId,
|
|
3050
3282
|
patientData,
|
|
@@ -3055,6 +3287,7 @@ function CollabPanel({
|
|
|
3055
3287
|
}) {
|
|
3056
3288
|
const { config } = useCollab();
|
|
3057
3289
|
const [showSettings, setShowSettings] = React4.useState(false);
|
|
3290
|
+
const [toast, setToast] = React4.useState(null);
|
|
3058
3291
|
const messageListRef = React4.useRef(null);
|
|
3059
3292
|
const {
|
|
3060
3293
|
conversation,
|
|
@@ -3068,6 +3301,7 @@ function CollabPanel({
|
|
|
3068
3301
|
replyTo,
|
|
3069
3302
|
setReplyTo,
|
|
3070
3303
|
sendMessage,
|
|
3304
|
+
retryMessage,
|
|
3071
3305
|
sendAudioMessage,
|
|
3072
3306
|
sendFileMessage,
|
|
3073
3307
|
sendTyping,
|
|
@@ -3092,10 +3326,33 @@ function CollabPanel({
|
|
|
3092
3326
|
try {
|
|
3093
3327
|
if (navigator.clipboard) {
|
|
3094
3328
|
await navigator.clipboard.writeText(text);
|
|
3329
|
+
setToast({ message: "Copied to clipboard" });
|
|
3095
3330
|
}
|
|
3096
3331
|
} catch {
|
|
3097
3332
|
}
|
|
3098
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
|
+
};
|
|
3099
3356
|
const pinDisabled = pinnedMessages.length >= MAX_PINNED_MESSAGES;
|
|
3100
3357
|
if (error) {
|
|
3101
3358
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyles.errorState, children: [
|
|
@@ -3106,78 +3363,83 @@ function CollabPanel({
|
|
|
3106
3363
|
if (isLoading && !conversation) {
|
|
3107
3364
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...panelStyles.container, ...style }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: panelStyles.loadingState, children: "Loading conversation..." }) });
|
|
3108
3365
|
}
|
|
3109
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3110
|
-
|
|
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,
|
|
3366
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...panelStyles.container, ...style }, children: [
|
|
3367
|
+
showSettings && conversation ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3368
|
+
ChannelSettings,
|
|
3130
3369
|
{
|
|
3131
|
-
|
|
3370
|
+
conversationId: conversation.id,
|
|
3371
|
+
channelName: conversation.name,
|
|
3372
|
+
channelPicture: conversation.picture,
|
|
3132
3373
|
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
3374
|
currentUserId: config.userId,
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
onPin: pinMessage,
|
|
3161
|
-
onUnpin: unpinMessage,
|
|
3162
|
-
onCopy: handleCopy,
|
|
3163
|
-
pinDisabled
|
|
3164
|
-
}
|
|
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)
|
|
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)
|
|
3175
3384
|
}
|
|
3176
|
-
)
|
|
3177
|
-
|
|
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
|
+
] });
|
|
3178
3439
|
}
|
|
3179
3440
|
var panelStyles = {
|
|
3180
3441
|
container: {
|
|
3442
|
+
position: "relative",
|
|
3181
3443
|
display: "flex",
|
|
3182
3444
|
flexDirection: "column",
|
|
3183
3445
|
height: "100%",
|
|
@@ -3312,7 +3574,7 @@ function CollabPopup({
|
|
|
3312
3574
|
ref: containerRef,
|
|
3313
3575
|
className,
|
|
3314
3576
|
style: {
|
|
3315
|
-
...
|
|
3577
|
+
...styles13.container,
|
|
3316
3578
|
left: position.x,
|
|
3317
3579
|
top: position.y,
|
|
3318
3580
|
width,
|
|
@@ -3321,14 +3583,14 @@ function CollabPopup({
|
|
|
3321
3583
|
},
|
|
3322
3584
|
onMouseDown: handleMouseDown,
|
|
3323
3585
|
children: [
|
|
3324
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-drag-handle": true, style:
|
|
3325
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3326
|
-
/* @__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: [
|
|
3327
3589
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3328
3590
|
"button",
|
|
3329
3591
|
{
|
|
3330
3592
|
onClick: () => setIsMinimized(!isMinimized),
|
|
3331
|
-
style:
|
|
3593
|
+
style: styles13.titleButton,
|
|
3332
3594
|
"aria-label": isMinimized ? "Expand chat" : "Minimize chat",
|
|
3333
3595
|
title: isMinimized ? "Expand" : "Minimize",
|
|
3334
3596
|
type: "button",
|
|
@@ -3339,7 +3601,7 @@ function CollabPopup({
|
|
|
3339
3601
|
"button",
|
|
3340
3602
|
{
|
|
3341
3603
|
onClick: onClose,
|
|
3342
|
-
style:
|
|
3604
|
+
style: styles13.titleButton,
|
|
3343
3605
|
"aria-label": "Close chat",
|
|
3344
3606
|
title: "Close",
|
|
3345
3607
|
type: "button",
|
|
@@ -3348,12 +3610,12 @@ function CollabPopup({
|
|
|
3348
3610
|
)
|
|
3349
3611
|
] })
|
|
3350
3612
|
] }),
|
|
3351
|
-
!isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3613
|
+
!isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(CollabPanel, { orderId, patientData, participantIds }) })
|
|
3352
3614
|
]
|
|
3353
3615
|
}
|
|
3354
3616
|
);
|
|
3355
3617
|
}
|
|
3356
|
-
var
|
|
3618
|
+
var styles13 = {
|
|
3357
3619
|
container: {
|
|
3358
3620
|
position: "fixed",
|
|
3359
3621
|
zIndex: 9999,
|
|
@@ -3658,11 +3920,11 @@ function CollabInline({
|
|
|
3658
3920
|
containerRef
|
|
3659
3921
|
} = useInlineCollab({ orderId, patientData, participantIds, messageLimit });
|
|
3660
3922
|
if (isLoading && !hasConversation) {
|
|
3661
|
-
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..." }) });
|
|
3662
3924
|
}
|
|
3663
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className, style: { ...
|
|
3664
|
-
hasConversation && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3665
|
-
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 }),
|
|
3666
3928
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3667
3929
|
InlineInputBar,
|
|
3668
3930
|
{
|
|
@@ -3679,12 +3941,12 @@ function CollabInline({
|
|
|
3679
3941
|
}
|
|
3680
3942
|
function InlineMessageRow({ message }) {
|
|
3681
3943
|
if (message.type === "system") {
|
|
3682
|
-
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 }) });
|
|
3683
3945
|
}
|
|
3684
3946
|
if (message.type === "audio" && message.mediaUrl) {
|
|
3685
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3947
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
|
|
3686
3948
|
/* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
|
|
3687
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3949
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
|
|
3688
3950
|
message.senderName,
|
|
3689
3951
|
":"
|
|
3690
3952
|
] }),
|
|
@@ -3692,13 +3954,13 @@ function InlineMessageRow({ message }) {
|
|
|
3692
3954
|
] });
|
|
3693
3955
|
}
|
|
3694
3956
|
const preview = renderMessagePreview(message);
|
|
3695
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3957
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.messageRow, children: [
|
|
3696
3958
|
/* @__PURE__ */ jsxRuntime.jsx(RoleDot, { role: message.senderRole }),
|
|
3697
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3959
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.senderName, children: [
|
|
3698
3960
|
message.senderName,
|
|
3699
3961
|
":"
|
|
3700
3962
|
] }),
|
|
3701
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3963
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.messageText, children: preview })
|
|
3702
3964
|
] });
|
|
3703
3965
|
}
|
|
3704
3966
|
function RoleDot({ role }) {
|
|
@@ -3708,7 +3970,7 @@ function RoleDot({ role }) {
|
|
|
3708
3970
|
physician: "#059669",
|
|
3709
3971
|
admin: "#dc2626"
|
|
3710
3972
|
};
|
|
3711
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3973
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
|
|
3712
3974
|
}
|
|
3713
3975
|
function InlineAudioPlayer({ url, duration }) {
|
|
3714
3976
|
const audioRef = React4.useRef(null);
|
|
@@ -3752,27 +4014,27 @@ function InlineAudioPlayer({ url, duration }) {
|
|
|
3752
4014
|
const total = duration ?? 0;
|
|
3753
4015
|
const remaining = Math.max(0, total - Math.floor(currentTime));
|
|
3754
4016
|
const displayTime = isPlaying ? remaining : total;
|
|
3755
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
4017
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles14.audioPlayer, children: [
|
|
3756
4018
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3757
4019
|
"button",
|
|
3758
4020
|
{
|
|
3759
4021
|
onClick: toggle,
|
|
3760
|
-
style:
|
|
4022
|
+
style: styles14.audioButton,
|
|
3761
4023
|
title: isPlaying ? "Pause" : "Play",
|
|
3762
4024
|
type: "button",
|
|
3763
4025
|
children: isPlaying ? "\u23F8" : "\u25B6"
|
|
3764
4026
|
}
|
|
3765
4027
|
),
|
|
3766
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3767
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3768
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3769
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3770
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3771
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3772
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...
|
|
3773
|
-
/* @__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%" } })
|
|
3774
4036
|
] }),
|
|
3775
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4037
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles14.audioDuration, children: formatDuration2(displayTime) }),
|
|
3776
4038
|
/* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, src: url, preload: "metadata" })
|
|
3777
4039
|
] });
|
|
3778
4040
|
}
|
|
@@ -3828,7 +4090,7 @@ function InlineInputBar({
|
|
|
3828
4090
|
},
|
|
3829
4091
|
[handleSend]
|
|
3830
4092
|
);
|
|
3831
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4093
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles14.inputBar, children: [
|
|
3832
4094
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3833
4095
|
"input",
|
|
3834
4096
|
{
|
|
@@ -3839,17 +4101,17 @@ function InlineInputBar({
|
|
|
3839
4101
|
onKeyDown: handleKeyDown,
|
|
3840
4102
|
placeholder,
|
|
3841
4103
|
disabled: isSending,
|
|
3842
|
-
style:
|
|
4104
|
+
style: styles14.input
|
|
3843
4105
|
}
|
|
3844
4106
|
),
|
|
3845
|
-
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3846
|
-
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" }),
|
|
3847
4109
|
text.trim() && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3848
4110
|
"button",
|
|
3849
4111
|
{
|
|
3850
4112
|
onClick: handleSend,
|
|
3851
4113
|
disabled: isSending,
|
|
3852
|
-
style:
|
|
4114
|
+
style: styles14.sendButton,
|
|
3853
4115
|
title: "Send message",
|
|
3854
4116
|
type: "button",
|
|
3855
4117
|
children: "\u27A4"
|
|
@@ -3859,7 +4121,7 @@ function InlineInputBar({
|
|
|
3859
4121
|
"button",
|
|
3860
4122
|
{
|
|
3861
4123
|
onClick: onExpand,
|
|
3862
|
-
style:
|
|
4124
|
+
style: styles14.expandButton,
|
|
3863
4125
|
title: "Expand to full chat",
|
|
3864
4126
|
type: "button",
|
|
3865
4127
|
children: "\u26F6"
|
|
@@ -3867,7 +4129,7 @@ function InlineInputBar({
|
|
|
3867
4129
|
)
|
|
3868
4130
|
] });
|
|
3869
4131
|
}
|
|
3870
|
-
var
|
|
4132
|
+
var styles14 = {
|
|
3871
4133
|
container: {
|
|
3872
4134
|
display: "flex",
|
|
3873
4135
|
flexDirection: "column",
|
|
@@ -4134,24 +4396,24 @@ function ConversationListItem({
|
|
|
4134
4396
|
className,
|
|
4135
4397
|
onClick,
|
|
4136
4398
|
style: {
|
|
4137
|
-
...
|
|
4138
|
-
...isSelected ?
|
|
4139
|
-
...hasUnread ?
|
|
4399
|
+
...styles15.container,
|
|
4400
|
+
...isSelected ? styles15.selected : {},
|
|
4401
|
+
...hasUnread ? styles15.unread : {}
|
|
4140
4402
|
},
|
|
4141
4403
|
type: "button",
|
|
4142
4404
|
children: [
|
|
4143
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4144
|
-
item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style:
|
|
4145
|
-
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 })
|
|
4146
4408
|
] }),
|
|
4147
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4148
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4409
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.content, children: [
|
|
4410
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.topRow, children: [
|
|
4149
4411
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4150
4412
|
"span",
|
|
4151
4413
|
{
|
|
4152
4414
|
style: {
|
|
4153
|
-
...
|
|
4154
|
-
...hasUnread ?
|
|
4415
|
+
...styles15.name,
|
|
4416
|
+
...hasUnread ? styles15.nameUnread : {}
|
|
4155
4417
|
},
|
|
4156
4418
|
children: displayName
|
|
4157
4419
|
}
|
|
@@ -4160,25 +4422,25 @@ function ConversationListItem({
|
|
|
4160
4422
|
"span",
|
|
4161
4423
|
{
|
|
4162
4424
|
style: {
|
|
4163
|
-
...
|
|
4164
|
-
...hasUnread ?
|
|
4425
|
+
...styles15.time,
|
|
4426
|
+
...hasUnread ? styles15.timeUnread : {}
|
|
4165
4427
|
},
|
|
4166
4428
|
children: formatInboxTimestamp(item.lastActivityAt)
|
|
4167
4429
|
}
|
|
4168
4430
|
)
|
|
4169
4431
|
] }),
|
|
4170
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4432
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.bottomRow, children: [
|
|
4171
4433
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4172
4434
|
"span",
|
|
4173
4435
|
{
|
|
4174
4436
|
style: {
|
|
4175
|
-
...
|
|
4176
|
-
...hasUnread ?
|
|
4437
|
+
...styles15.preview,
|
|
4438
|
+
...hasUnread ? styles15.previewUnread : {}
|
|
4177
4439
|
},
|
|
4178
4440
|
children: renderLastMessagePreview(item.lastMessage)
|
|
4179
4441
|
}
|
|
4180
4442
|
),
|
|
4181
|
-
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
4443
|
+
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
4182
4444
|
] })
|
|
4183
4445
|
] })
|
|
4184
4446
|
]
|
|
@@ -4206,7 +4468,7 @@ function renderLastMessagePreview(message) {
|
|
|
4206
4468
|
}
|
|
4207
4469
|
}
|
|
4208
4470
|
}
|
|
4209
|
-
var
|
|
4471
|
+
var styles15 = {
|
|
4210
4472
|
container: {
|
|
4211
4473
|
display: "flex",
|
|
4212
4474
|
alignItems: "center",
|
|
@@ -4353,30 +4615,30 @@ function ConversationList({
|
|
|
4353
4615
|
return result;
|
|
4354
4616
|
}, [conversations, query, showUnreadOnly]);
|
|
4355
4617
|
const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
|
|
4356
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style:
|
|
4357
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4358
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4359
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { style:
|
|
4360
|
-
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 })
|
|
4361
4623
|
] }),
|
|
4362
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4624
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4363
4625
|
"input",
|
|
4364
4626
|
{
|
|
4365
4627
|
type: "text",
|
|
4366
4628
|
value: query,
|
|
4367
4629
|
onChange: (e) => setQuery(e.target.value),
|
|
4368
4630
|
placeholder: "Search patients or channels...",
|
|
4369
|
-
style:
|
|
4631
|
+
style: styles16.searchInput
|
|
4370
4632
|
}
|
|
4371
4633
|
) }),
|
|
4372
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4634
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.filterRow, children: [
|
|
4373
4635
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4374
4636
|
"button",
|
|
4375
4637
|
{
|
|
4376
4638
|
onClick: () => setShowUnreadOnly(false),
|
|
4377
4639
|
style: {
|
|
4378
|
-
...
|
|
4379
|
-
...!showUnreadOnly ?
|
|
4640
|
+
...styles16.filterButton,
|
|
4641
|
+
...!showUnreadOnly ? styles16.filterButtonActive : {}
|
|
4380
4642
|
},
|
|
4381
4643
|
type: "button",
|
|
4382
4644
|
children: "All"
|
|
@@ -4387,8 +4649,8 @@ function ConversationList({
|
|
|
4387
4649
|
{
|
|
4388
4650
|
onClick: () => setShowUnreadOnly(true),
|
|
4389
4651
|
style: {
|
|
4390
|
-
...
|
|
4391
|
-
...showUnreadOnly ?
|
|
4652
|
+
...styles16.filterButton,
|
|
4653
|
+
...showUnreadOnly ? styles16.filterButtonActive : {}
|
|
4392
4654
|
},
|
|
4393
4655
|
type: "button",
|
|
4394
4656
|
children: [
|
|
@@ -4399,10 +4661,10 @@ function ConversationList({
|
|
|
4399
4661
|
)
|
|
4400
4662
|
] })
|
|
4401
4663
|
] }),
|
|
4402
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4403
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4404
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4405
|
-
!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" }),
|
|
4406
4668
|
filtered.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4407
4669
|
ConversationListItem,
|
|
4408
4670
|
{
|
|
@@ -4415,7 +4677,7 @@ function ConversationList({
|
|
|
4415
4677
|
] })
|
|
4416
4678
|
] });
|
|
4417
4679
|
}
|
|
4418
|
-
var
|
|
4680
|
+
var styles16 = {
|
|
4419
4681
|
container: {
|
|
4420
4682
|
display: "flex",
|
|
4421
4683
|
flexDirection: "column",
|
|
@@ -4520,8 +4782,8 @@ function CollabInbox({
|
|
|
4520
4782
|
setSelectedId(item.id);
|
|
4521
4783
|
onSelectConversation?.(item);
|
|
4522
4784
|
};
|
|
4523
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...
|
|
4524
|
-
/* @__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(
|
|
4525
4787
|
ConversationList,
|
|
4526
4788
|
{
|
|
4527
4789
|
conversations,
|
|
@@ -4532,13 +4794,13 @@ function CollabInbox({
|
|
|
4532
4794
|
title
|
|
4533
4795
|
}
|
|
4534
4796
|
) }),
|
|
4535
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4797
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.main, children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4536
4798
|
CollabPanel,
|
|
4537
4799
|
{
|
|
4538
4800
|
orderId: selected.orderId,
|
|
4539
4801
|
patientData: buildPatientData(selected),
|
|
4540
4802
|
showSeenBy: true,
|
|
4541
|
-
style:
|
|
4803
|
+
style: styles17.panel
|
|
4542
4804
|
},
|
|
4543
4805
|
selected.id
|
|
4544
4806
|
) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { hasAny: conversations.length > 0 }) })
|
|
@@ -4552,13 +4814,13 @@ function buildPatientData(item) {
|
|
|
4552
4814
|
};
|
|
4553
4815
|
}
|
|
4554
4816
|
function EmptyState({ hasAny }) {
|
|
4555
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
4556
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
4557
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { style:
|
|
4558
|
-
/* @__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" })
|
|
4559
4821
|
] });
|
|
4560
4822
|
}
|
|
4561
|
-
var
|
|
4823
|
+
var styles17 = {
|
|
4562
4824
|
container: {
|
|
4563
4825
|
display: "flex",
|
|
4564
4826
|
height: "100%",
|