@natoe/colab 0.1.1 → 0.1.3

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useCallback, useState, useContext, useMemo } from 'react';
1
+ import React4, { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useCallback, useState, useContext, useMemo } from 'react';
2
2
  import { Socket, Presence } from 'phoenix';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
 
@@ -1153,7 +1153,7 @@ var styles = {
1153
1153
  },
1154
1154
  patientName: {
1155
1155
  fontWeight: 600,
1156
- fontSize: "15px",
1156
+ fontSize: "17px",
1157
1157
  color: "#111827"
1158
1158
  },
1159
1159
  secondaryRow: {
@@ -1163,8 +1163,8 @@ var styles = {
1163
1163
  alignItems: "center"
1164
1164
  },
1165
1165
  secondary: {
1166
- fontSize: "12px",
1167
- color: "#6b7280"
1166
+ fontSize: "13px",
1167
+ color: "#4b5563"
1168
1168
  },
1169
1169
  actions: {
1170
1170
  display: "flex",
@@ -1172,8 +1172,9 @@ var styles = {
1172
1172
  marginTop: "8px"
1173
1173
  },
1174
1174
  dicomButton: {
1175
- padding: "6px 12px",
1176
- fontSize: "13px",
1175
+ minHeight: "40px",
1176
+ padding: "8px 16px",
1177
+ fontSize: "14px",
1177
1178
  fontWeight: 500,
1178
1179
  color: "#ffffff",
1179
1180
  backgroundColor: "#2563eb",
@@ -1182,8 +1183,9 @@ var styles = {
1182
1183
  cursor: "pointer"
1183
1184
  },
1184
1185
  settingsButton: {
1185
- padding: "6px 12px",
1186
- fontSize: "13px",
1186
+ minHeight: "40px",
1187
+ padding: "8px 16px",
1188
+ fontSize: "14px",
1187
1189
  fontWeight: 500,
1188
1190
  color: "#374151",
1189
1191
  backgroundColor: "#ffffff",
@@ -1424,6 +1426,40 @@ var styles4 = {
1424
1426
  cursor: "pointer"
1425
1427
  }
1426
1428
  };
1429
+ function FileIcon({ size = 18, color = "currentColor" }) {
1430
+ return /* @__PURE__ */ jsx(
1431
+ "svg",
1432
+ {
1433
+ xmlns: "http://www.w3.org/2000/svg",
1434
+ width: size,
1435
+ height: size,
1436
+ viewBox: "0 0 24 24",
1437
+ fill: color,
1438
+ "aria-hidden": "true",
1439
+ children: /* @__PURE__ */ 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" })
1440
+ }
1441
+ );
1442
+ }
1443
+ function PinIcon({ size = 14, color = "currentColor" }) {
1444
+ return /* @__PURE__ */ jsx(
1445
+ "svg",
1446
+ {
1447
+ xmlns: "http://www.w3.org/2000/svg",
1448
+ width: size,
1449
+ height: size,
1450
+ viewBox: "0 0 24 24",
1451
+ fill: color,
1452
+ "aria-hidden": "true",
1453
+ children: /* @__PURE__ */ 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" })
1454
+ }
1455
+ );
1456
+ }
1457
+ var ROLE_LABELS = {
1458
+ radiologist: "Radiologist",
1459
+ lab: "Imaging Center",
1460
+ physician: "Physician",
1461
+ admin: "Admin"
1462
+ };
1427
1463
  function MessageBubble({
1428
1464
  message,
1429
1465
  isOwn,
@@ -1463,7 +1499,10 @@ function MessageBubble({
1463
1499
  ...isOwn ? styles5.ownBubble : styles5.otherBubble
1464
1500
  },
1465
1501
  children: [
1466
- message.isPinned && /* @__PURE__ */ jsx("div", { style: styles5.pinnedBadge, children: "\u{1F4CC} Pinned" }),
1502
+ message.isPinned && /* @__PURE__ */ jsxs("div", { style: styles5.pinnedBadge, children: [
1503
+ /* @__PURE__ */ jsx(PinIcon, { size: 12 }),
1504
+ /* @__PURE__ */ jsx("span", { children: "Pinned" })
1505
+ ] }),
1467
1506
  message.replyToSnapshot && /* @__PURE__ */ jsx(
1468
1507
  ReplyQuoteBlock,
1469
1508
  {
@@ -1558,7 +1597,7 @@ function ImageContent({ mediaUrl, fileName }) {
1558
1597
  function FileContent({ mediaUrl, fileName }) {
1559
1598
  if (!mediaUrl) return null;
1560
1599
  return /* @__PURE__ */ jsxs("a", { href: mediaUrl, target: "_blank", rel: "noopener noreferrer", style: styles5.fileLink, children: [
1561
- /* @__PURE__ */ jsx("span", { style: styles5.fileIcon, children: "\u{1F4C4}" }),
1600
+ /* @__PURE__ */ jsx(FileIcon, { size: 20 }),
1562
1601
  /* @__PURE__ */ jsx("span", { style: styles5.fileName, children: fileName || "Download file" })
1563
1602
  ] });
1564
1603
  }
@@ -1596,7 +1635,7 @@ function RoleBadge({ role }) {
1596
1635
  physician: "#059669",
1597
1636
  admin: "#dc2626"
1598
1637
  };
1599
- return /* @__PURE__ */ jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: role });
1638
+ return /* @__PURE__ */ jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: ROLE_LABELS[role] ?? role });
1600
1639
  }
1601
1640
  function formatTime(iso) {
1602
1641
  try {
@@ -1625,7 +1664,7 @@ var styles5 = {
1625
1664
  maxWidth: "75%"
1626
1665
  },
1627
1666
  bubble: {
1628
- padding: "8px 12px",
1667
+ padding: "10px 14px",
1629
1668
  borderRadius: "12px",
1630
1669
  wordBreak: "break-word"
1631
1670
  },
@@ -1640,11 +1679,13 @@ var styles5 = {
1640
1679
  borderBottomLeftRadius: "4px"
1641
1680
  },
1642
1681
  pinnedBadge: {
1643
- display: "inline-block",
1644
- fontSize: "10px",
1682
+ display: "inline-flex",
1683
+ alignItems: "center",
1684
+ gap: "4px",
1685
+ fontSize: "12px",
1645
1686
  fontWeight: 600,
1646
1687
  marginBottom: "4px",
1647
- opacity: 0.7
1688
+ color: "#6b7280"
1648
1689
  },
1649
1690
  senderRow: {
1650
1691
  display: "flex",
@@ -1653,24 +1694,25 @@ var styles5 = {
1653
1694
  marginBottom: "4px"
1654
1695
  },
1655
1696
  senderName: {
1656
- fontSize: "12px",
1697
+ fontSize: "13px",
1657
1698
  fontWeight: 600,
1658
1699
  color: "#374151"
1659
1700
  },
1660
1701
  roleBadge: {
1661
- fontSize: "10px",
1662
- fontWeight: 500,
1663
- padding: "1px 6px",
1702
+ fontSize: "11px",
1703
+ fontWeight: 600,
1704
+ padding: "2px 8px",
1664
1705
  borderRadius: "4px"
1665
1706
  },
1666
1707
  textBody: {
1667
1708
  margin: 0,
1668
- fontSize: "14px",
1669
- lineHeight: "1.4"
1709
+ fontSize: "15px",
1710
+ lineHeight: "1.45"
1670
1711
  },
1671
1712
  timestamp: {
1672
- fontSize: "10px",
1673
- opacity: 0.7,
1713
+ fontSize: "12px",
1714
+ color: "inherit",
1715
+ opacity: 0.8,
1674
1716
  marginTop: "4px",
1675
1717
  textAlign: "right"
1676
1718
  },
@@ -1709,9 +1751,6 @@ var styles5 = {
1709
1751
  color: "inherit",
1710
1752
  padding: "6px 0"
1711
1753
  },
1712
- fileIcon: {
1713
- fontSize: "18px"
1714
- },
1715
1754
  fileName: {
1716
1755
  fontSize: "13px",
1717
1756
  textDecoration: "underline"
@@ -1746,15 +1785,91 @@ var styles5 = {
1746
1785
  justifyContent: "center",
1747
1786
  alignItems: "center",
1748
1787
  gap: "8px",
1749
- padding: "4px 16px",
1750
- fontSize: "12px",
1751
- color: "#9ca3af"
1788
+ padding: "6px 16px",
1789
+ fontSize: "13px",
1790
+ color: "#6b7280"
1752
1791
  },
1753
1792
  systemTime: {
1754
- fontSize: "10px",
1755
- color: "#d1d5db"
1793
+ fontSize: "12px",
1794
+ color: "#9ca3af"
1756
1795
  }
1757
1796
  };
1797
+
1798
+ // src/core/dateLabels.ts
1799
+ var SHORT_MONTHS = [
1800
+ "Jan",
1801
+ "Feb",
1802
+ "Mar",
1803
+ "Apr",
1804
+ "May",
1805
+ "Jun",
1806
+ "Jul",
1807
+ "Aug",
1808
+ "Sep",
1809
+ "Oct",
1810
+ "Nov",
1811
+ "Dec"
1812
+ ];
1813
+ var LONG_WEEKDAYS = [
1814
+ "Sunday",
1815
+ "Monday",
1816
+ "Tuesday",
1817
+ "Wednesday",
1818
+ "Thursday",
1819
+ "Friday",
1820
+ "Saturday"
1821
+ ];
1822
+ var ONE_DAY_MS = 864e5;
1823
+ function parseSafe(iso) {
1824
+ const d = new Date(iso);
1825
+ return Number.isNaN(d.getTime()) ? null : d;
1826
+ }
1827
+ function startOfDay(d) {
1828
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate());
1829
+ }
1830
+ function daysBetween(a, b) {
1831
+ return Math.floor((startOfDay(a).getTime() - startOfDay(b).getTime()) / ONE_DAY_MS);
1832
+ }
1833
+ function formatFullDate(d) {
1834
+ return `${d.getDate()} ${SHORT_MONTHS[d.getMonth()]} ${d.getFullYear()}`;
1835
+ }
1836
+ function formatLocaleTime(d) {
1837
+ try {
1838
+ return d.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
1839
+ } catch {
1840
+ const h = d.getHours();
1841
+ const m = d.getMinutes().toString().padStart(2, "0");
1842
+ const suffix = h >= 12 ? "PM" : "AM";
1843
+ const h12 = (h + 11) % 12 + 1;
1844
+ return `${h12}:${m} ${suffix}`;
1845
+ }
1846
+ }
1847
+ function formatInboxTimestamp(iso) {
1848
+ if (!iso) return "";
1849
+ const d = parseSafe(iso);
1850
+ if (!d) return "";
1851
+ const diffDays = daysBetween(/* @__PURE__ */ new Date(), d);
1852
+ if (diffDays === 0) return formatLocaleTime(d);
1853
+ if (diffDays === 1) return "Yesterday";
1854
+ if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];
1855
+ return formatFullDate(d);
1856
+ }
1857
+ function formatDayDivider(iso) {
1858
+ if (!iso) return "";
1859
+ const d = parseSafe(iso);
1860
+ if (!d) return "";
1861
+ const diffDays = daysBetween(/* @__PURE__ */ new Date(), d);
1862
+ if (diffDays === 0) return "Today";
1863
+ if (diffDays === 1) return "Yesterday";
1864
+ if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];
1865
+ return formatFullDate(d);
1866
+ }
1867
+ function dayBucketKey(iso) {
1868
+ if (!iso) return "";
1869
+ const d = parseSafe(iso);
1870
+ if (!d) return "";
1871
+ return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1872
+ }
1758
1873
  var MessageList = forwardRef(function MessageList2({
1759
1874
  messages,
1760
1875
  currentUserId,
@@ -1840,22 +1955,30 @@ var MessageList = forwardRef(function MessageList2({
1840
1955
  /* @__PURE__ */ jsx("p", { style: styles6.emptyTitle, children: "No messages yet" }),
1841
1956
  /* @__PURE__ */ jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation about this study" })
1842
1957
  ] }),
1843
- messages.map((message) => /* @__PURE__ */ jsx("div", { "data-message-id": message.id, children: /* @__PURE__ */ jsx(
1844
- MessageBubble,
1845
- {
1846
- message,
1847
- isOwn: message.senderId === currentUserId,
1848
- participants,
1849
- currentUserId,
1850
- showSeenBy,
1851
- onDeepLinkClick,
1852
- onReply,
1853
- onPin,
1854
- onUnpin,
1855
- onCopy,
1856
- pinDisabled
1857
- }
1858
- ) }, message.id)),
1958
+ messages.map((message, index) => {
1959
+ const currentBucket = dayBucketKey(message.insertedAt);
1960
+ const prevBucket = index === 0 ? null : dayBucketKey(messages[index - 1].insertedAt);
1961
+ const showDivider = currentBucket && currentBucket !== prevBucket;
1962
+ return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
1963
+ showDivider && /* @__PURE__ */ jsx("div", { style: styles6.dayDivider, role: "separator", "aria-label": "Date", children: /* @__PURE__ */ jsx("span", { style: styles6.dayDividerPill, children: formatDayDivider(message.insertedAt) }) }),
1964
+ /* @__PURE__ */ jsx("div", { "data-message-id": message.id, children: /* @__PURE__ */ jsx(
1965
+ MessageBubble,
1966
+ {
1967
+ message,
1968
+ isOwn: message.senderId === currentUserId,
1969
+ participants,
1970
+ currentUserId,
1971
+ showSeenBy,
1972
+ onDeepLinkClick,
1973
+ onReply,
1974
+ onPin,
1975
+ onUnpin,
1976
+ onCopy,
1977
+ pinDisabled
1978
+ }
1979
+ ) })
1980
+ ] }, message.id);
1981
+ }),
1859
1982
  typingUsers.length > 0 && /* @__PURE__ */ jsxs("div", { style: styles6.typingIndicator, children: [
1860
1983
  typingUsers.map((t) => t.userName ?? "Someone").join(", "),
1861
1984
  typingUsers.length === 1 ? " is " : " are ",
@@ -1881,18 +2004,19 @@ var styles6 = {
1881
2004
  loadingMore: {
1882
2005
  textAlign: "center",
1883
2006
  padding: "12px",
1884
- fontSize: "13px",
1885
- color: "#9ca3af"
2007
+ fontSize: "14px",
2008
+ color: "#6b7280"
1886
2009
  },
1887
2010
  loadMoreButton: {
1888
2011
  display: "block",
1889
2012
  margin: "0 auto 12px",
1890
- padding: "6px 16px",
1891
- fontSize: "12px",
1892
- color: "#6b7280",
2013
+ minHeight: "36px",
2014
+ padding: "8px 18px",
2015
+ fontSize: "13px",
2016
+ color: "#374151",
1893
2017
  backgroundColor: "transparent",
1894
- border: "1px solid #e5e7eb",
1895
- borderRadius: "16px",
2018
+ border: "1px solid #d1d5db",
2019
+ borderRadius: "18px",
1896
2020
  cursor: "pointer"
1897
2021
  },
1898
2022
  empty: {
@@ -1901,22 +2025,38 @@ var styles6 = {
1901
2025
  alignItems: "center",
1902
2026
  justifyContent: "center",
1903
2027
  padding: "48px 16px",
1904
- color: "#9ca3af"
2028
+ color: "#6b7280"
1905
2029
  },
1906
2030
  emptyTitle: {
1907
- fontSize: "15px",
1908
- fontWeight: 500,
2031
+ fontSize: "16px",
2032
+ fontWeight: 600,
2033
+ color: "#374151",
1909
2034
  margin: "0 0 4px"
1910
2035
  },
1911
2036
  emptySubtitle: {
1912
- fontSize: "13px",
2037
+ fontSize: "14px",
1913
2038
  margin: 0
1914
2039
  },
1915
2040
  typingIndicator: {
1916
2041
  padding: "4px 16px 8px",
1917
- fontSize: "12px",
1918
- color: "#9ca3af",
2042
+ fontSize: "13px",
2043
+ color: "#6b7280",
1919
2044
  fontStyle: "italic"
2045
+ },
2046
+ dayDivider: {
2047
+ display: "flex",
2048
+ justifyContent: "center",
2049
+ margin: "12px 0 8px"
2050
+ },
2051
+ dayDividerPill: {
2052
+ display: "inline-block",
2053
+ padding: "5px 14px",
2054
+ fontSize: "13px",
2055
+ fontWeight: 500,
2056
+ color: "#334155",
2057
+ backgroundColor: "#e2e8f0",
2058
+ borderRadius: "12px",
2059
+ letterSpacing: "0.2px"
1920
2060
  }
1921
2061
  };
1922
2062
  function ReplyPreview({ message, onCancel, className }) {
@@ -2011,6 +2151,48 @@ var styles7 = {
2011
2151
  flexShrink: 0
2012
2152
  }
2013
2153
  };
2154
+ function AttachIcon({ size = 20, color = "currentColor" }) {
2155
+ return /* @__PURE__ */ jsx(
2156
+ "svg",
2157
+ {
2158
+ xmlns: "http://www.w3.org/2000/svg",
2159
+ width: size,
2160
+ height: size,
2161
+ viewBox: "0 0 24 24",
2162
+ fill: color,
2163
+ "aria-hidden": "true",
2164
+ children: /* @__PURE__ */ 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" })
2165
+ }
2166
+ );
2167
+ }
2168
+ function SendIcon({ size = 20, color = "currentColor" }) {
2169
+ return /* @__PURE__ */ jsx(
2170
+ "svg",
2171
+ {
2172
+ xmlns: "http://www.w3.org/2000/svg",
2173
+ width: size,
2174
+ height: size,
2175
+ viewBox: "0 0 24 24",
2176
+ fill: color,
2177
+ "aria-hidden": "true",
2178
+ children: /* @__PURE__ */ jsx("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
2179
+ }
2180
+ );
2181
+ }
2182
+ function CloseIcon({ size = 18, color = "currentColor" }) {
2183
+ return /* @__PURE__ */ jsx(
2184
+ "svg",
2185
+ {
2186
+ xmlns: "http://www.w3.org/2000/svg",
2187
+ width: size,
2188
+ height: size,
2189
+ viewBox: "0 0 24 24",
2190
+ fill: color,
2191
+ "aria-hidden": "true",
2192
+ children: /* @__PURE__ */ 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" })
2193
+ }
2194
+ );
2195
+ }
2014
2196
  function MessageInput({
2015
2197
  onSendText,
2016
2198
  // MIC DISABLED — onSendAudio still accepted but unused.
@@ -2099,7 +2281,19 @@ function MessageInput({
2099
2281
  );
2100
2282
  return /* @__PURE__ */ jsxs("div", { className, style: styles8.container, children: [
2101
2283
  replyTo && onCancelReply && /* @__PURE__ */ jsx(ReplyPreview, { message: replyTo, onCancel: onCancelReply }),
2102
- fileError && /* @__PURE__ */ jsx("div", { style: styles8.error, children: fileError }),
2284
+ fileError && /* @__PURE__ */ jsxs("div", { style: styles8.error, role: "alert", children: [
2285
+ /* @__PURE__ */ jsx("span", { style: styles8.errorText, children: fileError }),
2286
+ /* @__PURE__ */ jsx(
2287
+ "button",
2288
+ {
2289
+ type: "button",
2290
+ onClick: () => setFileError(null),
2291
+ "aria-label": "Dismiss error",
2292
+ style: styles8.errorDismiss,
2293
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: 16 })
2294
+ }
2295
+ )
2296
+ ] }),
2103
2297
  /* @__PURE__ */ jsxs("div", { style: styles8.inputBar, children: [
2104
2298
  /* @__PURE__ */ jsx(
2105
2299
  "button",
@@ -2107,9 +2301,10 @@ function MessageInput({
2107
2301
  onClick: () => fileInputRef.current?.click(),
2108
2302
  disabled: disabled || isSending,
2109
2303
  style: styles8.iconButton,
2304
+ "aria-label": "Attach file",
2110
2305
  title: "Attach file",
2111
2306
  type: "button",
2112
- children: "\u{1F4CE}"
2307
+ children: /* @__PURE__ */ jsx(AttachIcon, { size: 22, color: "#374151" })
2113
2308
  }
2114
2309
  ),
2115
2310
  /* @__PURE__ */ jsx(
@@ -2142,12 +2337,14 @@ function MessageInput({
2142
2337
  {
2143
2338
  onClick: handleSendText,
2144
2339
  disabled: disabled || isSending || !text.trim(),
2340
+ "aria-label": "Send message",
2341
+ title: "Send message",
2145
2342
  style: {
2146
2343
  ...styles8.sendButton,
2147
2344
  opacity: text.trim() ? 1 : 0.4
2148
2345
  },
2149
2346
  type: "button",
2150
- children: "\u27A4"
2347
+ children: /* @__PURE__ */ jsx(SendIcon, { size: 20, color: "#ffffff" })
2151
2348
  }
2152
2349
  )
2153
2350
  ] })
@@ -2159,24 +2356,45 @@ var styles8 = {
2159
2356
  backgroundColor: "#ffffff"
2160
2357
  },
2161
2358
  error: {
2162
- padding: "6px 16px",
2163
- fontSize: "12px",
2164
- color: "#dc2626",
2165
- backgroundColor: "#fef2f2"
2359
+ display: "flex",
2360
+ alignItems: "center",
2361
+ justifyContent: "space-between",
2362
+ gap: "8px",
2363
+ padding: "8px 12px 8px 16px",
2364
+ fontSize: "13px",
2365
+ color: "#b91c1c",
2366
+ backgroundColor: "#fef2f2",
2367
+ borderTop: "1px solid #fecaca"
2368
+ },
2369
+ errorText: {
2370
+ flex: 1,
2371
+ minWidth: 0
2372
+ },
2373
+ errorDismiss: {
2374
+ width: "28px",
2375
+ height: "28px",
2376
+ display: "flex",
2377
+ alignItems: "center",
2378
+ justifyContent: "center",
2379
+ backgroundColor: "transparent",
2380
+ border: "none",
2381
+ color: "#b91c1c",
2382
+ borderRadius: "4px",
2383
+ cursor: "pointer",
2384
+ flexShrink: 0
2166
2385
  },
2167
2386
  inputBar: {
2168
2387
  display: "flex",
2169
2388
  alignItems: "flex-end",
2170
- gap: "4px",
2171
- padding: "8px 12px"
2389
+ gap: "6px",
2390
+ padding: "10px 12px"
2172
2391
  },
2173
2392
  iconButton: {
2174
- width: "36px",
2175
- height: "36px",
2393
+ width: "44px",
2394
+ height: "44px",
2176
2395
  display: "flex",
2177
2396
  alignItems: "center",
2178
2397
  justifyContent: "center",
2179
- fontSize: "18px",
2180
2398
  backgroundColor: "transparent",
2181
2399
  border: "none",
2182
2400
  borderRadius: "50%",
@@ -2185,23 +2403,23 @@ var styles8 = {
2185
2403
  },
2186
2404
  textarea: {
2187
2405
  flex: 1,
2188
- padding: "8px 12px",
2189
- fontSize: "14px",
2190
- lineHeight: "1.4",
2191
- border: "1px solid #e5e7eb",
2192
- borderRadius: "20px",
2406
+ padding: "10px 14px",
2407
+ fontSize: "15px",
2408
+ lineHeight: "1.45",
2409
+ border: "1px solid #d1d5db",
2410
+ borderRadius: "22px",
2193
2411
  resize: "none",
2194
2412
  outline: "none",
2195
2413
  fontFamily: "inherit",
2196
- maxHeight: "120px"
2414
+ maxHeight: "120px",
2415
+ minHeight: "44px"
2197
2416
  },
2198
2417
  sendButton: {
2199
- width: "36px",
2200
- height: "36px",
2418
+ width: "44px",
2419
+ height: "44px",
2201
2420
  display: "flex",
2202
2421
  alignItems: "center",
2203
2422
  justifyContent: "center",
2204
- fontSize: "18px",
2205
2423
  backgroundColor: "#2563eb",
2206
2424
  color: "#ffffff",
2207
2425
  border: "none",
@@ -2992,6 +3210,34 @@ var panelStyles = {
2992
3210
  margin: 0
2993
3211
  }
2994
3212
  };
3213
+ function MinimizeIcon({ size = 18, color = "currentColor" }) {
3214
+ return /* @__PURE__ */ jsx(
3215
+ "svg",
3216
+ {
3217
+ xmlns: "http://www.w3.org/2000/svg",
3218
+ width: size,
3219
+ height: size,
3220
+ viewBox: "0 0 24 24",
3221
+ fill: color,
3222
+ "aria-hidden": "true",
3223
+ children: /* @__PURE__ */ jsx("path", { d: "M6 19h12v2H6z" })
3224
+ }
3225
+ );
3226
+ }
3227
+ function ExpandIcon({ size = 18, color = "currentColor" }) {
3228
+ return /* @__PURE__ */ jsx(
3229
+ "svg",
3230
+ {
3231
+ xmlns: "http://www.w3.org/2000/svg",
3232
+ width: size,
3233
+ height: size,
3234
+ viewBox: "0 0 24 24",
3235
+ fill: color,
3236
+ "aria-hidden": "true",
3237
+ children: /* @__PURE__ */ jsx("path", { d: "M4 4h16v16H4V4zm2 4v10h12V8H6z" })
3238
+ }
3239
+ );
3240
+ }
2995
3241
  function CollabPopup({
2996
3242
  orderId,
2997
3243
  patientData,
@@ -3040,7 +3286,7 @@ function CollabPopup({
3040
3286
  const handleMouseMove = (e) => {
3041
3287
  setPosition({
3042
3288
  x: Math.max(0, Math.min(e.clientX - dragOffset.current.x, window.innerWidth - width)),
3043
- y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ? 48 : height)))
3289
+ y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ? 52 : height)))
3044
3290
  });
3045
3291
  };
3046
3292
  const handleMouseUp = () => {
@@ -3064,7 +3310,7 @@ function CollabPopup({
3064
3310
  left: position.x,
3065
3311
  top: position.y,
3066
3312
  width,
3067
- height: isMinimized ? 48 : height,
3313
+ height: isMinimized ? 52 : height,
3068
3314
  cursor: isDragging ? "grabbing" : "default"
3069
3315
  },
3070
3316
  onMouseDown: handleMouseDown,
@@ -3077,12 +3323,23 @@ function CollabPopup({
3077
3323
  {
3078
3324
  onClick: () => setIsMinimized(!isMinimized),
3079
3325
  style: styles12.titleButton,
3326
+ "aria-label": isMinimized ? "Expand chat" : "Minimize chat",
3080
3327
  title: isMinimized ? "Expand" : "Minimize",
3081
3328
  type: "button",
3082
- children: isMinimized ? "\u25A2" : "\u2014"
3329
+ children: isMinimized ? /* @__PURE__ */ jsx(ExpandIcon, { size: 16, color: "#cbd5e1" }) : /* @__PURE__ */ jsx(MinimizeIcon, { size: 16, color: "#cbd5e1" })
3083
3330
  }
3084
3331
  ),
3085
- /* @__PURE__ */ jsx("button", { onClick: onClose, style: styles12.titleButton, title: "Close", type: "button", children: "\u2715" })
3332
+ /* @__PURE__ */ jsx(
3333
+ "button",
3334
+ {
3335
+ onClick: onClose,
3336
+ style: styles12.titleButton,
3337
+ "aria-label": "Close chat",
3338
+ title: "Close",
3339
+ type: "button",
3340
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: 16, color: "#cbd5e1" })
3341
+ }
3342
+ )
3086
3343
  ] })
3087
3344
  ] }),
3088
3345
  !isMinimized && /* @__PURE__ */ jsx("div", { style: styles12.panelWrapper, children: /* @__PURE__ */ jsx(CollabPanel, { orderId, patientData, participantIds }) })
@@ -3107,15 +3364,15 @@ var styles12 = {
3107
3364
  display: "flex",
3108
3365
  justifyContent: "space-between",
3109
3366
  alignItems: "center",
3110
- padding: "0 12px",
3111
- height: "48px",
3367
+ padding: "0 8px 0 14px",
3368
+ height: "52px",
3112
3369
  backgroundColor: "#1e293b",
3113
3370
  cursor: "grab",
3114
3371
  userSelect: "none",
3115
3372
  flexShrink: 0
3116
3373
  },
3117
3374
  titleText: {
3118
- fontSize: "13px",
3375
+ fontSize: "15px",
3119
3376
  fontWeight: 500,
3120
3377
  color: "#ffffff",
3121
3378
  overflow: "hidden",
@@ -3128,17 +3385,16 @@ var styles12 = {
3128
3385
  flexShrink: 0
3129
3386
  },
3130
3387
  titleButton: {
3131
- width: "28px",
3132
- height: "28px",
3388
+ width: "40px",
3389
+ height: "40px",
3133
3390
  display: "flex",
3134
3391
  alignItems: "center",
3135
3392
  justifyContent: "center",
3136
3393
  backgroundColor: "transparent",
3137
3394
  border: "none",
3138
- borderRadius: "4px",
3395
+ borderRadius: "6px",
3139
3396
  cursor: "pointer",
3140
- fontSize: "13px",
3141
- color: "#94a3b8"
3397
+ color: "#cbd5e1"
3142
3398
  },
3143
3399
  panelWrapper: {
3144
3400
  flex: 1,
@@ -3901,7 +4157,7 @@ function ConversationListItem({
3901
4157
  ...styles14.time,
3902
4158
  ...hasUnread ? styles14.timeUnread : {}
3903
4159
  },
3904
- children: formatRelativeTime(item.lastActivityAt)
4160
+ children: formatInboxTimestamp(item.lastActivityAt)
3905
4161
  }
3906
4162
  )
3907
4163
  ] }),
@@ -3944,23 +4200,6 @@ function renderLastMessagePreview(message) {
3944
4200
  }
3945
4201
  }
3946
4202
  }
3947
- function formatRelativeTime(iso) {
3948
- try {
3949
- const date = new Date(iso);
3950
- const now = /* @__PURE__ */ new Date();
3951
- const diffMs = now.getTime() - date.getTime();
3952
- const diffMin = Math.floor(diffMs / 6e4);
3953
- const diffHr = Math.floor(diffMs / 36e5);
3954
- const diffDay = Math.floor(diffMs / 864e5);
3955
- if (diffMin < 1) return "now";
3956
- if (diffMin < 60) return `${diffMin}m`;
3957
- if (diffHr < 24) return `${diffHr}h`;
3958
- if (diffDay < 7) return `${diffDay}d`;
3959
- return date.toLocaleDateString([], { month: "short", day: "numeric" });
3960
- } catch {
3961
- return "";
3962
- }
3963
- }
3964
4203
  var styles14 = {
3965
4204
  container: {
3966
4205
  display: "flex",
@@ -4026,7 +4265,7 @@ var styles14 = {
4026
4265
  gap: "8px"
4027
4266
  },
4028
4267
  name: {
4029
- fontSize: "14px",
4268
+ fontSize: "15px",
4030
4269
  fontWeight: 500,
4031
4270
  color: "#111827",
4032
4271
  overflow: "hidden",
@@ -4039,8 +4278,8 @@ var styles14 = {
4039
4278
  fontWeight: 700
4040
4279
  },
4041
4280
  time: {
4042
- fontSize: "11px",
4043
- color: "#9ca3af",
4281
+ fontSize: "12px",
4282
+ color: "#6b7280",
4044
4283
  flexShrink: 0
4045
4284
  },
4046
4285
  timeUnread: {
@@ -4054,8 +4293,8 @@ var styles14 = {
4054
4293
  gap: "8px"
4055
4294
  },
4056
4295
  preview: {
4057
- fontSize: "13px",
4058
- color: "#6b7280",
4296
+ fontSize: "14px",
4297
+ color: "#4b5563",
4059
4298
  overflow: "hidden",
4060
4299
  textOverflow: "ellipsis",
4061
4300
  whiteSpace: "nowrap",