@natoe/colab 0.1.13 β†’ 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/constants.ts","../src/core/caseConvert.ts","../src/core/socket.ts","../src/core/theme.ts","../src/core/styles.ts","../src/context/CollabProvider.tsx","../src/core/channelName.ts","../src/hooks/useConversation.ts","../src/hooks/useChannelSettings.ts","../src/hooks/useDeepLinks.ts","../src/components/icons/DicomIcon.tsx","../src/components/icons/SettingsIcon.tsx","../src/components/icons/BackIcon.tsx","../src/components/PatientHeader.tsx","../src/components/ReplyQuoteBlock.tsx","../src/components/SeenByIndicator.tsx","../src/components/icons/ReplyIcon.tsx","../src/components/icons/PinIcon.tsx","../src/components/icons/CopyIcon.tsx","../src/components/icons/MoreIcon.tsx","../src/components/MessageActionsMenu.tsx","../src/components/icons/FileIcon.tsx","../src/components/icons/AlertIcon.tsx","../src/components/Spinner.tsx","../src/components/MessageBubble.tsx","../src/components/icons/ChatIllustration.tsx","../src/core/dateLabels.ts","../src/components/MessageList.tsx","../src/components/ReplyPreview.tsx","../src/components/icons/AttachIcon.tsx","../src/components/icons/SendIcon.tsx","../src/components/icons/CloseIcon.tsx","../src/components/MessageInput.tsx","../src/components/ParticipantsList.tsx","../src/components/ChannelSettings.tsx","../src/components/PinnedMessagesBar.tsx","../src/components/Toast.tsx","../src/components/CollabPanel.tsx","../src/components/icons/MinimizeIcon.tsx","../src/components/CollabPopup.tsx","../src/hooks/useInlineCollab.ts","../src/components/CollabInline.tsx","../src/hooks/useConversationList.ts","../src/components/ConversationListItem.tsx","../src/components/icons/SearchIcon.tsx","../src/components/ConversationList.tsx","../src/components/CollabInbox.tsx","../src/hooks/useMessages.ts","../src/hooks/useAudioRecorder.ts","../src/hooks/useUnreadCount.ts","../src/hooks/usePinnedMessages.ts"],"names":["Socket","Presence","createContext","useContext","useState","useRef","useEffect","useCallback","jsx","jsxs","styles","useLayoutEffect","menu","createPortal","escapeRegex","forwardRef","MessageList","useImperativeHandle","React","RoleBadge","Fragment","useId","formatDuration","computeInitials","useMemo","EmptyState"],"mappings":"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","file":"index.js","sourcesContent":["/** Phoenix channel event names β€” must match backend channel implementation */\nexport const EVENTS = {\n MESSAGE_NEW: 'message:new',\n MESSAGE_READ: 'message:read',\n MESSAGE_PINNED: 'message:pinned',\n MESSAGE_UNPINNED: 'message:unpinned',\n USER_TYPING: 'user:typing',\n USER_JOINED: 'user:joined',\n USER_LEFT: 'user:left',\n CHANNEL_UPDATED: 'channel:updated',\n CHANNEL_DELETED: 'channel:deleted',\n PRESENCE_STATE: 'presence_state',\n PRESENCE_DIFF: 'presence_diff',\n} as const;\n\n/** Maximum number of pinned messages allowed per conversation */\nexport const MAX_PINNED_MESSAGES = 3;\n\n/** Message types */\nexport const MESSAGE_TYPES = {\n TEXT: 'text',\n AUDIO: 'audio',\n IMAGE: 'image',\n FILE: 'file',\n SYSTEM: 'system',\n DEEP_LINK: 'deep_link',\n} as const;\n\n/** Deep link protocol prefix */\nexport const DEEP_LINK_PREFIX = 'natoe://';\n\n/** Typing indicator debounce in ms */\nexport const TYPING_DEBOUNCE_MS = 2000;\n\n/** Messages to load per page when scrolling back */\nexport const MESSAGES_PAGE_SIZE = 30;\n\n/** Supported audio MIME type for recording */\nexport const AUDIO_MIME_TYPE = 'audio/webm;codecs=opus';\n\n/** Supported image types for attachments */\nexport const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];\n\n/** Max file size in bytes (20MB) */\nexport const MAX_FILE_SIZE = 20 * 1024 * 1024;\n","/**\n * Recursively converts object keys from snake_case to camelCase.\n *\n * Used at every backend boundary (REST responses, socket events) to bridge\n * the Phoenix (snake_case) β†’ TypeScript (camelCase) gap.\n *\n * Idempotent β€” keys already in camelCase stay unchanged (no underscores to\n * convert). Arrays and primitives pass through untouched.\n */\nexport function snakeToCamel<T = unknown>(input: unknown): T {\n if (Array.isArray(input)) {\n return input.map((item) => snakeToCamel(item)) as unknown as T;\n }\n\n if (input !== null && typeof input === 'object') {\n const source = input as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n const camelKey = toCamelKey(key);\n out[camelKey] = snakeToCamel(source[key]);\n }\n return out as T;\n }\n\n return input as T;\n}\n\nfunction toCamelKey(key: string): string {\n if (!key.includes('_')) return key;\n return key.replace(/_([a-zA-Z0-9])/g, (_, c: string) => c.toUpperCase());\n}\n","import { Socket, Channel, Presence } from 'phoenix';\nimport type {\n CollabConfig,\n Message,\n Conversation,\n Participant,\n SendMessagePayload,\n TypingEvent,\n ChannelUpdatePayload,\n InviteUserPayload,\n} from './types';\nimport { EVENTS } from './constants';\nimport { snakeToCamel } from './caseConvert';\n\ntype MessageCallback = (message: Message) => void;\ntype TypingCallback = (event: TypingEvent) => void;\ntype ParticipantCallback = (participant: Participant) => void;\ntype ChannelUpdateCallback = (conversation: Partial<Conversation>) => void;\ntype PresenceCallback = (presences: Record<string, { userId: string; isOnline: boolean }>) => void;\n\ninterface ConversationCallbacks {\n onMessage?: MessageCallback;\n onTyping?: TypingCallback;\n onUserJoined?: ParticipantCallback;\n onUserLeft?: ParticipantCallback;\n onChannelUpdated?: ChannelUpdateCallback;\n onChannelDeleted?: () => void;\n onPresence?: PresenceCallback;\n onMessageRead?: (data: { messageId: string; userId: string }) => void;\n onMessagePinned?: (message: Message) => void;\n onMessageUnpinned?: (data: { messageId: string }) => void;\n}\n\n/**\n * Manages Phoenix WebSocket connection and channel subscriptions.\n * One instance per authenticated user session.\n */\nexport class CollabSocket {\n private socket: Socket | null = null;\n private channels: Map<string, Channel> = new Map();\n private presences: Map<string, Presence> = new Map();\n private userChannel: Channel | null = null;\n private config: CollabConfig | null = null;\n private onUnreadUpdate: ((counts: Record<string, number>) => void) | null = null;\n\n /** Connect to Phoenix WebSocket server. Idempotent β€” safe to call when\n * the token becomes available later (e.g. after async login) without\n * stacking up multiple open sockets. */\n connect(config: CollabConfig): void {\n this.config = config;\n\n // No token means the host hasn't finished login yet. Skip the connect\n // so we don't churn through reconnect attempts that the server would\n // reject with 1006 anyway. The host re-calls connect() once auth lands.\n if (!config.getToken()) {\n return;\n }\n\n // If a prior (live or half-dead) socket exists, retire it before\n // creating a new one. Otherwise the old heartbeat / channels leak.\n if (this.socket) {\n if (this.socket.isConnected()) return;\n try {\n this.socket.disconnect();\n } catch {\n // best-effort; we're about to replace it anyway\n }\n this.channels.clear();\n this.presences.clear();\n this.userChannel = null;\n }\n\n this.socket = new Socket(config.socketUrl, {\n params: () => ({ token: config.getToken() }),\n });\n\n // Phoenix's onError hands us the native WebSocket error/close event. We\n // forward whatever useful fields the browser gave us so failures like a\n // 403 handshake (bad token / missing Redis session) can be distinguished\n // from transport drops instead of all showing as \"error undefined\".\n this.socket.onError((err) => {\n const closeEvent = err as unknown as CloseEvent | undefined;\n config.onError?.({\n code: 'SOCKET_ERROR',\n message: 'WebSocket connection error',\n details: closeEvent\n ? {\n type: closeEvent.type,\n code: closeEvent.code,\n reason: closeEvent.reason,\n wasClean: closeEvent.wasClean,\n }\n : err,\n });\n });\n\n this.socket.onClose((event) => {\n // Code 1006 = abnormal closure (no close frame β€” usually means the\n // server rejected the upgrade, e.g. auth failed before handshake).\n // Code 1000 = normal; code 1011 = server error.\n config.onError?.({\n code: 'SOCKET_CLOSED',\n message: `Socket closed (code ${event?.code ?? 'unknown'})`,\n details: event\n ? { code: event.code, reason: event.reason, wasClean: event.wasClean }\n : undefined,\n });\n });\n\n this.socket.connect();\n this.joinUserChannel();\n }\n\n /** Subscribe to user-level events (unread counts, notifications) */\n private joinUserChannel(): void {\n if (!this.socket || !this.config) return;\n\n // Topic has no user_id suffix β€” backend derives it from the authenticated socket.\n // This avoids any mismatch between client-side stored IDs and the token's claims.\n this.userChannel = this.socket.channel('user_notifications', {});\n\n this.userChannel.on('unread_update', (payload: Record<string, number>) => {\n this.onUnreadUpdate?.(payload);\n });\n\n this.userChannel\n .join()\n .receive('ok', () => {\n // connected to user channel\n })\n .receive('error', (reason) => {\n this.config?.onError?.({\n code: 'USER_CHANNEL_ERROR',\n message: 'Failed to join user channel',\n details: reason,\n });\n });\n }\n\n /** Register callback for unread count changes */\n onUnreadCountUpdate(callback: (counts: Record<string, number>) => void): void {\n this.onUnreadUpdate = callback;\n }\n\n /** Join a conversation channel and subscribe to events */\n joinConversation(conversationId: string, callbacks: ConversationCallbacks): Channel | null {\n if (!this.socket) return null;\n\n // Don't rejoin if already in this channel\n if (this.channels.has(conversationId)) {\n return this.channels.get(conversationId)!;\n }\n\n const channel = this.socket.channel(`conversation:${conversationId}`, {});\n\n // Real-time message delivery\n if (callbacks.onMessage) {\n channel.on(EVENTS.MESSAGE_NEW, (payload: unknown) => {\n callbacks.onMessage!(snakeToCamel<Message>(payload));\n });\n }\n\n // Typing indicators\n if (callbacks.onTyping) {\n channel.on(EVENTS.USER_TYPING, (payload: unknown) => {\n callbacks.onTyping!(snakeToCamel<TypingEvent>(payload));\n });\n }\n\n // Participant events\n if (callbacks.onUserJoined) {\n channel.on(EVENTS.USER_JOINED, (payload: unknown) => {\n callbacks.onUserJoined!(snakeToCamel<Participant>(payload));\n });\n }\n\n if (callbacks.onUserLeft) {\n channel.on(EVENTS.USER_LEFT, (payload: unknown) => {\n callbacks.onUserLeft!(snakeToCamel<Participant>(payload));\n });\n }\n\n // Channel metadata changes\n if (callbacks.onChannelUpdated) {\n channel.on(EVENTS.CHANNEL_UPDATED, (payload: unknown) => {\n callbacks.onChannelUpdated!(snakeToCamel<Partial<Conversation>>(payload));\n });\n }\n\n if (callbacks.onChannelDeleted) {\n channel.on(EVENTS.CHANNEL_DELETED, () => {\n callbacks.onChannelDeleted!();\n });\n }\n\n // Read receipts\n if (callbacks.onMessageRead) {\n channel.on(EVENTS.MESSAGE_READ, (payload: unknown) => {\n callbacks.onMessageRead!(snakeToCamel<{ messageId: string; userId: string }>(payload));\n });\n }\n\n // Pin events\n if (callbacks.onMessagePinned) {\n channel.on(EVENTS.MESSAGE_PINNED, (payload: unknown) => {\n callbacks.onMessagePinned!(snakeToCamel<Message>(payload));\n });\n }\n\n if (callbacks.onMessageUnpinned) {\n channel.on(EVENTS.MESSAGE_UNPINNED, (payload: unknown) => {\n callbacks.onMessageUnpinned!(snakeToCamel<{ messageId: string }>(payload));\n });\n }\n\n // Presence tracking (online/offline)\n if (callbacks.onPresence) {\n const presence = new Presence(channel);\n\n presence.onSync(() => {\n const online: Record<string, { userId: string; isOnline: boolean }> = {};\n presence.list((id: string) => {\n online[id] = { userId: id, isOnline: true };\n });\n callbacks.onPresence!(online);\n });\n\n this.presences.set(conversationId, presence);\n }\n\n channel\n .join()\n .receive('ok', () => {\n // successfully joined conversation channel\n })\n .receive('error', (reason) => {\n this.config?.onError?.({\n code: 'CHANNEL_JOIN_ERROR',\n message: `Failed to join conversation ${conversationId}`,\n details: reason,\n });\n });\n\n this.channels.set(conversationId, channel);\n return channel;\n }\n\n /** Leave a conversation channel */\n leaveConversation(conversationId: string): void {\n const channel = this.channels.get(conversationId);\n if (channel) {\n channel.leave();\n this.channels.delete(conversationId);\n this.presences.delete(conversationId);\n }\n }\n\n /** Send a message to a conversation.\n *\n * Phoenix buffers pushes fired while a channel is still joining and\n * replays them on successful join. The default per-push timeout is 10s,\n * which is tight on slow dev backends β€” we bump to 30s so a late join\n * doesn't surface as a \"timed out\" error to a message that ultimately\n * persists. The caller still gets 'ok' once the server acks.\n */\n sendMessage(conversationId: string, payload: SendMessagePayload): Promise<Message> {\n return new Promise((resolve, reject) => {\n const channel = this.channels.get(conversationId);\n if (!channel) {\n reject({ code: 'NOT_JOINED', message: 'Not joined to this conversation' });\n return;\n }\n\n // If the underlying socket is down (token cleared, server restarted\n // mid-session, etc.) Phoenix will silently buffer the push until the\n // per-push timeout fires 30s later. Fail fast instead β€” the caller\n // can remove the optimistic row and the user can retry once we're\n // back online.\n if (!this.socket?.isConnected()) {\n reject({\n code: 'SOCKET_DISCONNECTED',\n message: 'Cannot send β€” chat server not connected',\n });\n return;\n }\n\n channel\n .push(EVENTS.MESSAGE_NEW, payload, 30_000)\n .receive('ok', (response: Message) => resolve(response))\n .receive('error', (reason) =>\n reject({ code: 'SEND_ERROR', message: 'Failed to send message', details: reason })\n )\n .receive('timeout', () =>\n reject({ code: 'TIMEOUT', message: 'Message send timed out' })\n );\n });\n }\n\n /** Broadcast typing indicator */\n sendTyping(conversationId: string, isTyping: boolean): void {\n const channel = this.channels.get(conversationId);\n channel?.push(EVENTS.USER_TYPING, {\n userId: this.config?.userId,\n userName: this.config?.userName,\n isTyping,\n });\n }\n\n /** Mark messages as read */\n markAsRead(conversationId: string, messageId: string): void {\n const channel = this.channels.get(conversationId);\n channel?.push(EVENTS.MESSAGE_READ, {\n messageId,\n userId: this.config?.userId,\n });\n }\n\n // ── Channel Management ──\n\n /** Add a user to the conversation */\n inviteUser(conversationId: string, payload: InviteUserPayload): Promise<Participant> {\n return this.channelPush(conversationId, 'invite_user', payload);\n }\n\n /** Remove a user from the conversation */\n removeUser(conversationId: string, userId: string): Promise<void> {\n return this.channelPush(conversationId, 'remove_user', { userId });\n }\n\n /** Update channel name/picture */\n updateChannel(conversationId: string, payload: ChannelUpdatePayload): Promise<Conversation> {\n return this.channelPush(conversationId, 'update_channel', payload);\n }\n\n /** Delete channel (admin only) */\n deleteChannel(conversationId: string): Promise<void> {\n return this.channelPush(conversationId, 'delete_channel', {});\n }\n\n /** Pin a message in the conversation (max MAX_PINNED_MESSAGES) */\n pinMessage(conversationId: string, messageId: string): Promise<Message> {\n return this.channelPush(conversationId, 'pin_message', { messageId });\n }\n\n /** Unpin a message in the conversation */\n unpinMessage(conversationId: string, messageId: string): Promise<void> {\n return this.channelPush(conversationId, 'unpin_message', { messageId });\n }\n\n /** Generic push with promise wrapper */\n private channelPush<T>(conversationId: string, event: string, payload: object): Promise<T> {\n return new Promise((resolve, reject) => {\n const channel = this.channels.get(conversationId);\n if (!channel) {\n reject({ code: 'NOT_JOINED', message: 'Not joined to this conversation' });\n return;\n }\n\n channel\n .push(event, payload)\n .receive('ok', (response: T) => resolve(response))\n .receive('error', (reason) =>\n reject({ code: 'CHANNEL_ERROR', message: `Failed: ${event}`, details: reason })\n );\n });\n }\n\n /** Check if connected */\n isConnected(): boolean {\n return this.socket?.isConnected() ?? false;\n }\n\n /** Disconnect socket and leave all channels */\n disconnect(): void {\n this.channels.forEach((channel) => channel.leave());\n this.channels.clear();\n this.presences.clear();\n this.userChannel?.leave();\n this.socket?.disconnect();\n this.socket = null;\n this.config = null;\n }\n}\n","/**\n * Design tokens β€” the single source of truth for every visual value used\n * by the package. Components import from here instead of hard-coding pixel\n * values, so the scale stays coherent and a future theming pass can swap\n * these for CSS variables without touching every component.\n *\n * Conventions:\n * - Font sizes: modular scale (~1.18 ratio), nothing under 12px. Older\n * users at 100% zoom can still read everything that carries meaning.\n * - Spacing: 4px baseline grid (S1=4, S2=8, … S12=48). Combine, don't add\n * ad-hoc values.\n * - Radii: named buckets (\"md\" for buttons/cards, \"lg\" for bubbles).\n * - Colors: brand + neutral grayscale + a small semantic set. No more\n * hex literals in component files.\n */\n\n// ── Typography ─────────────────────────────────────────────────────────────\n\nexport const FONT_SIZE = {\n xs: '12px',\n sm: '13px',\n md: '15px',\n lg: '17px',\n xl: '20px',\n xxl: '28px',\n} as const;\n\nexport const FONT_WEIGHT = {\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n} as const;\n\nexport const LINE_HEIGHT = {\n tight: 1.3,\n normal: 1.45,\n loose: 1.6,\n} as const;\n\n// ── Spacing ────────────────────────────────────────────────────────────────\n// 4px baseline. Use S1..S12; if you want 6px or 10px you almost certainly\n// want S1 or S2 instead.\n\nexport const SPACE = {\n S1: '4px',\n S2: '8px',\n S3: '12px',\n S4: '16px',\n S5: '20px',\n S6: '24px',\n S8: '32px',\n S10: '40px',\n S12: '48px',\n} as const;\n\n// ── Radii ──────────────────────────────────────────────────────────────────\n\nexport const RADIUS = {\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n pill: '9999px',\n full: '50%',\n} as const;\n\n// ── Colors ─────────────────────────────────────────────────────────────────\n//\n// The brand + semantic colors are emitted as CSS variables by\n// ensureGlobalStyles() in core/styles.ts, with the hex literals below as\n// defaults. Host apps override individual variables via\n// CollabConfig.theme β€” components don't need to know whether they're\n// rendering the default or an override since they consume these tokens\n// either way.\n//\n// Neutrals and slate are kept as hex literals because changing them\n// wholesale breaks the package's tonal balance β€” those aren't part of\n// the theming surface.\n\n/** CSS variable names for the themeable color tokens. */\nexport const THEME_VAR = {\n primary: '--natoe-colab-primary',\n primaryHover: '--natoe-colab-primary-hover',\n primaryBg: '--natoe-colab-primary-bg',\n primaryFg: '--natoe-colab-primary-fg',\n success: '--natoe-colab-success',\n warning: '--natoe-colab-warning',\n danger: '--natoe-colab-danger',\n dangerBg: '--natoe-colab-danger-bg',\n dangerBorder: '--natoe-colab-danger-border',\n dangerFg: '--natoe-colab-danger-fg',\n fontStack: '--natoe-colab-font-stack',\n} as const;\n\n/** Default values for the themeable tokens (used by both CSS emission and\n * the inline-style fallback inside `var(..., fallback)`). */\nexport const THEME_DEFAULTS = {\n primary: '#2563eb',\n primaryHover: '#1d4ed8',\n primaryBg: '#dbeafe',\n primaryFg: '#1d4ed8',\n success: '#059669',\n warning: '#d97706',\n danger: '#dc2626',\n dangerBg: '#fef2f2',\n dangerBorder: '#fecaca',\n dangerFg: '#b91c1c',\n fontStack:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n} as const;\n\n/** Public override shape β€” passed via CollabConfig.theme. Every key is\n * optional; unspecified keys fall back to {@link THEME_DEFAULTS}. */\nexport type Theme = Partial<Record<keyof typeof THEME_DEFAULTS, string>>;\n\nconst cssVar = (name: string, fallback: string): string => `var(${name}, ${fallback})`;\n\nexport const COLOR = {\n // Brand β€” themeable\n primary: cssVar(THEME_VAR.primary, THEME_DEFAULTS.primary),\n primaryHover: cssVar(THEME_VAR.primaryHover, THEME_DEFAULTS.primaryHover),\n /** Tinted surface for chips/cards on brand-coloured states. */\n primaryBg: cssVar(THEME_VAR.primaryBg, THEME_DEFAULTS.primaryBg),\n primaryFg: cssVar(THEME_VAR.primaryFg, THEME_DEFAULTS.primaryFg),\n\n // Neutral grayscale β€” not themeable, taken from Tailwind's zinc-leaning\n // slate to match the package's existing tonal balance.\n white: '#ffffff',\n neutral50: '#f9fafb',\n neutral100: '#f3f4f6',\n neutral200: '#e5e7eb',\n neutral300: '#d1d5db',\n neutral400: '#9ca3af',\n neutral500: '#6b7280',\n neutral600: '#4b5563',\n neutral700: '#374151',\n neutral800: '#1f2937',\n neutral900: '#111827',\n\n // Slate (used by day dividers + dialog title bar) β€” not themeable.\n slate200: '#e2e8f0',\n slate500: '#64748b',\n slate700: '#334155',\n slate800: '#1e293b',\n\n // Semantic β€” themeable\n success: cssVar(THEME_VAR.success, THEME_DEFAULTS.success),\n warning: cssVar(THEME_VAR.warning, THEME_DEFAULTS.warning),\n danger: cssVar(THEME_VAR.danger, THEME_DEFAULTS.danger),\n dangerBg: cssVar(THEME_VAR.dangerBg, THEME_DEFAULTS.dangerBg),\n dangerBorder: cssVar(THEME_VAR.dangerBorder, THEME_DEFAULTS.dangerBorder),\n dangerFg: cssVar(THEME_VAR.dangerFg, THEME_DEFAULTS.dangerFg),\n} as const;\n\n// ── Sizes / hit targets ────────────────────────────────────────────────────\n// Centralised so any \"interactive\" element gets a consistent 40-44px tap area.\n\nexport const SIZE = {\n /** Default interactive height (text buttons, list rows). */\n control: '40px',\n /** Square icon-only buttons inside chrome (popup title, menu trigger). */\n controlIcon: '36px',\n /** Primary input controls (textarea send/attach). 44px = WCAG min. */\n controlPrimary: '44px',\n /** Avatar in the inbox row. */\n avatar: '40px',\n /** Unread dot. */\n dot: '10px',\n} as const;\n\n// ── Shadow / elevation ─────────────────────────────────────────────────────\n\nexport const SHADOW = {\n /** Cards / floating popovers (message-actions menu). */\n popover: '0 6px 18px rgba(0, 0, 0, 0.12)',\n /** Dialog (CollabPopup). */\n dialog: '0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)',\n /** Subtle separator shadow (sticky day divider, toast). */\n subtle: '0 1px 2px rgba(0, 0, 0, 0.04)',\n toast: '0 4px 12px rgba(0, 0, 0, 0.18)',\n} as const;\n\n// ── Z-index buckets ────────────────────────────────────────────────────────\n\nexport const Z_INDEX = {\n /** Sticky day divider β€” above bubbles, below interactive popovers. */\n sticky: 1,\n /** Toasts inside a panel. */\n toast: 20,\n /** Floating CollabPopup dialog. */\n dialog: 9999,\n /** Portaled message-actions menu β€” must sit above the dialog. */\n menu: 10000,\n} as const;\n","/**\n * Shared style tokens + the global stylesheet the package injects once per\n * page.\n *\n * Top-level wrappers (CollabPopup, CollabPanel, CollabInline, CollabInbox)\n * import {@link FONT_STACK} so every surface renders with the same font\n * stack, even when the package is mounted inside an iframe whose\n * surrounding document doesn't set one.\n *\n * Themeable tokens (brand + semantic colors + the font stack) are emitted\n * as CSS custom properties on `:root` so host apps can override them via\n * `CollabConfig.theme` (see {@link applyThemeOverrides}). Non-themeable\n * tokens (neutrals, slate, spacing, radius, sizes) live as inline values\n * in core/theme.ts and stay constant.\n *\n * The prefers-contrast / prefers-reduced-motion adjustments are emitted\n * inside the same stylesheet so they apply wherever a `natoe-colab-root`\n * wrapper is mounted.\n */\n\nimport { THEME_DEFAULTS, THEME_VAR, type Theme } from './theme';\n\n/** CSS variable reference for the font stack (with the canonical default). */\nexport const FONT_STACK = `var(${THEME_VAR.fontStack}, ${THEME_DEFAULTS.fontStack})`;\n\n/** Class applied to every top-level wrapper so global styles can scope to us. */\nexport const ROOT_CLASS = 'natoe-colab-root';\n\nconst GLOBAL_STYLE_ID = 'natoe-colab-global-styles';\n\n/** :root declarations for the themeable token defaults, joined into one rule. */\nconst ROOT_DEFAULTS_BLOCK = (Object.keys(THEME_DEFAULTS) as Array<keyof typeof THEME_DEFAULTS>)\n .map((key) => ` ${THEME_VAR[key]}: ${THEME_DEFAULTS[key]};`)\n .join('\\n');\n\nconst GLOBAL_CSS = `\n:root {\n${ROOT_DEFAULTS_BLOCK}\n}\n\n@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }\n\n@keyframes natoe-colab-message-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* High-contrast adjustments β€” older users on OS-level high-contrast mode\n get heavier borders and stronger text without losing the package look. */\n@media (prefers-contrast: more) {\n .${ROOT_CLASS} {\n color: #000000;\n }\n .${ROOT_CLASS} button {\n outline: 1px solid currentColor;\n }\n}\n\n/* Honour reduced-motion preferences by killing entry animations. */\n@media (prefers-reduced-motion: reduce) {\n .${ROOT_CLASS} [data-natoe-message-bubble] {\n animation: none !important;\n }\n}\n`;\n\n/**\n * Idempotently inject the package's shared CSS (custom properties +\n * keyframes + media queries). Safe to call from any component constructor β€”\n * repeat calls are a no-op.\n */\nexport function ensureGlobalStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById(GLOBAL_STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = GLOBAL_STYLE_ID;\n style.textContent = GLOBAL_CSS;\n document.head.appendChild(style);\n}\n\n/**\n * Apply a host-supplied theme by setting CSS custom properties on the\n * document root. Keys missing from `theme` have their previously-set\n * override cleared so toggling overrides back to undefined returns the\n * default β€” never leaves stale values behind.\n */\nexport function applyThemeOverrides(theme: Theme | undefined): void {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n (Object.keys(THEME_VAR) as Array<keyof typeof THEME_VAR>).forEach((key) => {\n const value = theme?.[key];\n if (value) {\n root.style.setProperty(THEME_VAR[key], value);\n } else {\n root.style.removeProperty(THEME_VAR[key]);\n }\n });\n}\n","import React, { createContext, useContext, useEffect, useRef, useState, useCallback } from 'react';\nimport { CollabSocket } from '../core/socket';\nimport type {\n CollabConfig,\n ConversationListItem,\n ConversationPreview,\n CreateConversationResponse,\n Message,\n PreviewBatchResponse,\n SendMessagePayload,\n} from '../core/types';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\nimport { snakeToCamel } from '../core/caseConvert';\nimport { applyThemeOverrides } from '../core/styles';\n\ninterface FetchMessagesOptions {\n before?: string;\n limit?: number;\n}\n\ninterface CreateConversationOptions {\n name: string;\n participantIds?: string[];\n}\n\ninterface CollabContextValue {\n socket: CollabSocket;\n config: CollabConfig;\n apiBaseUrl: string;\n totalUnread: number;\n /**\n * Per-conversation unread counts, keyed by conversation ID. Updated\n * live via the user_notifications channel's unread_update push, so\n * surfaces like a minimized-chat chip can reflect changes without\n * mounting their own useConversation.\n */\n unreadCounts: Record<string, number>;\n /** Batched preview lookup β€” coalesces calls within a microtask */\n requestPreview: (orderId: string) => Promise<ConversationPreview | null>;\n /** Invalidate a cached preview (e.g. when a new message arrives) */\n invalidatePreview: (orderId: string) => void;\n /** Fetch paginated message history */\n fetchMessages: (conversationId: string, options?: FetchMessagesOptions) => Promise<Message[]>;\n /** Atomic create-or-send β€” creates conversation if missing, then stores the first message */\n createConversationWithMessage: (\n orderId: string,\n message: SendMessagePayload,\n options: CreateConversationOptions\n ) => Promise<CreateConversationResponse>;\n /** Add a user to an existing conversation (e.g. when radiologist is assigned later) */\n addParticipant: (conversationId: string, userId: string) => Promise<void>;\n /** Remove a user from a conversation */\n removeParticipant: (conversationId: string, userId: string) => Promise<void>;\n /** Fetch the current user's full conversation list β€” feeds the CollabInbox sidebar */\n fetchConversationList: () => Promise<ConversationListItem[]>;\n /** Pin a message (max MAX_PINNED_MESSAGES per conversation β€” backend enforces) */\n pinMessage: (conversationId: string, messageId: string) => Promise<void>;\n /** Unpin a message */\n unpinMessage: (conversationId: string, messageId: string) => Promise<void>;\n /** Fetch current pinned messages for a conversation */\n fetchPinnedMessages: (conversationId: string) => Promise<Message[]>;\n}\n\nexport const CollabContext = createContext<CollabContextValue | null>(null);\nexport type { CollabContextValue };\n\nexport function useCollab(): CollabContextValue {\n const context = useContext(CollabContext);\n if (!context) {\n throw new Error('useCollab must be used within a <CollabProvider>');\n }\n return context;\n}\n\ninterface CollabProviderProps {\n config: CollabConfig;\n children: React.ReactNode;\n /** REST API base URL for the Phoenix backend (e.g. https://backend.natoe.ai) */\n apiBaseUrl: string;\n}\n\nexport function CollabProvider({ config, apiBaseUrl, children }: CollabProviderProps) {\n // Using useState (not useRef) so children re-render once the socket is ready.\n // Instantiated synchronously on first render so children have a non-null\n // socket reference immediately; the ACTUAL connect() happens in the\n // effect below, after the unread-count handler is wired in β€” otherwise\n // the backend's initial :after_join push races the handler registration\n // and the first unread_update is dropped silently.\n const [socket, setSocket] = useState<CollabSocket | null>(() => {\n if (typeof window === 'undefined') return null;\n return new CollabSocket();\n });\n const [unreadCounts, setUnreadCounts] = useState<Record<string, number>>({});\n\n // Preview batching state\n const pendingOrderIds = useRef<Set<string>>(new Set());\n const pendingResolvers = useRef<Map<string, Array<(preview: ConversationPreview | null) => void>>>(new Map());\n const previewCache = useRef<Map<string, ConversationPreview | null>>(new Map());\n const batchScheduled = useRef(false);\n\n // Apply host theme overrides to the document root as CSS custom\n // properties. Re-runs whenever the theme prop reference changes so a\n // host that rebuilds its config object (e.g. on locale/brand switch)\n // sees the new colors immediately. Keys absent from the new theme\n // object are explicitly cleared so toggling them back to undefined\n // restores the package defaults β€” no stale values.\n useEffect(() => {\n applyThemeOverrides(config.theme);\n }, [config.theme]);\n\n // Wire unread-count listener + reconnect when identity changes.\n // The socket instance (wrapper) is created lazily in useState above, but\n // the underlying Phoenix Socket is only created if getToken() returned\n // something at that first render. When the token arrives later (post-login),\n // this effect re-fires and asks the wrapper to connect for real.\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n // Create the wrapper if it wasn't created during the useState init\n // (e.g. SSR branch that short-circuited).\n let s = socket;\n if (!s) {\n s = new CollabSocket();\n setSocket(s);\n }\n\n // Register the unread handler BEFORE connect() so the backend's\n // :after_join push (initial counts, fires immediately on channel join)\n // is never dropped because the handler was still unset. Push-driven\n // updates also clear the preview cache so the next popup open fetches\n // fresh server truth.\n s.onUnreadCountUpdate((counts) => {\n setUnreadCounts(counts);\n previewCache.current.clear();\n });\n\n // connect() is idempotent β€” no-op when already connected, retries when\n // the prior init saw an empty token.\n if (!s.isConnected()) {\n s.connect(config);\n }\n\n // Intentionally no cleanup disconnect here β€” identity changes should\n // reconnect in place rather than tearing down the whole session.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [config.socketUrl, config.userId]);\n\n const authHeaders = useCallback(\n (): HeadersInit => ({\n Authorization: `Bearer ${config.getToken()}`,\n 'Content-Type': 'application/json',\n }),\n [config]\n );\n\n // ── Batch preview fetching ──────────────────────────────────────────\n\n const flushPreviewBatch = useCallback(async () => {\n const orderIds = Array.from(pendingOrderIds.current);\n const resolvers = new Map(pendingResolvers.current);\n pendingOrderIds.current.clear();\n pendingResolvers.current.clear();\n batchScheduled.current = false;\n\n if (orderIds.length === 0) return;\n\n try {\n const query = orderIds.map((id) => `order_ids[]=${encodeURIComponent(id)}`).join('&');\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/conversations/previews?${query}`, {\n headers: authHeaders(),\n });\n\n if (!response.ok) throw new Error(`Preview batch failed: ${response.status}`);\n\n const data: PreviewBatchResponse = snakeToCamel(await response.json());\n\n orderIds.forEach((orderId) => {\n const preview = data.previews[orderId] ?? null;\n if (preview !== null) {\n previewCache.current.set(orderId, preview);\n }\n resolvers.get(orderId)?.forEach((resolve) => resolve(preview));\n });\n } catch (error) {\n config.onError?.({\n code: 'PREVIEW_BATCH_ERROR',\n message: 'Failed to fetch conversation previews',\n details: error,\n });\n orderIds.forEach((orderId) => {\n resolvers.get(orderId)?.forEach((resolve) => resolve(null));\n });\n }\n }, [apiBaseUrl, authHeaders, config]);\n\n const requestPreview = useCallback(\n (orderId: string): Promise<ConversationPreview | null> => {\n // Return cached if available\n if (previewCache.current.has(orderId)) {\n return Promise.resolve(previewCache.current.get(orderId) ?? null);\n }\n\n return new Promise((resolve) => {\n pendingOrderIds.current.add(orderId);\n const existing = pendingResolvers.current.get(orderId) || [];\n existing.push(resolve);\n pendingResolvers.current.set(orderId, existing);\n\n if (!batchScheduled.current) {\n batchScheduled.current = true;\n queueMicrotask(flushPreviewBatch);\n }\n });\n },\n [flushPreviewBatch]\n );\n\n const invalidatePreview = useCallback((orderId: string) => {\n previewCache.current.delete(orderId);\n }, []);\n\n // ── Message history ──────────────────────────────────────────\n\n const fetchMessages = useCallback(\n async (conversationId: string, options: FetchMessagesOptions = {}): Promise<Message[]> => {\n const limit = options.limit ?? MESSAGES_PAGE_SIZE;\n const params = new URLSearchParams({ limit: String(limit) });\n if (options.before) params.set('before', options.before);\n\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages?${params.toString()}`,\n { headers: authHeaders() }\n );\n\n if (!response.ok) {\n throw { code: 'FETCH_ERROR', message: 'Failed to fetch messages', status: response.status };\n }\n\n const msgs: Message[] = snakeToCamel(await response.json());\n return msgs.sort((a, b) => a.insertedAt.localeCompare(b.insertedAt));\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Atomic create-or-send ──────────────────────────────────────────\n\n const createConversationWithMessage = useCallback(\n async (\n orderId: string,\n message: SendMessagePayload,\n options: CreateConversationOptions\n ): Promise<CreateConversationResponse> => {\n if (!orderId || !orderId.trim()) {\n throw {\n code: 'INVALID_ORDER_ID',\n message:\n 'Cannot create conversation: orderId is empty. Host app passed an order with no orderId/mainOrderId set.',\n };\n }\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/orders/${orderId}/messages`, {\n method: 'POST',\n headers: authHeaders(),\n body: JSON.stringify({\n message,\n conversation: {\n name: options.name,\n participant_ids: options.participantIds ?? [],\n },\n }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw { code: 'CREATE_ERROR', message: 'Failed to create conversation', details: error };\n }\n\n const data: CreateConversationResponse = snakeToCamel(await response.json());\n\n // The backend may have appended this message to an EXISTING\n // study-scoped conversation that already has plenty of history.\n // Drop the cached preview so the next requestPreview fetches truth\n // instead of reading a stale snapshot from before the new message.\n previewCache.current.delete(orderId);\n\n return data;\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Participant management ──────────────────────────────────────────\n\n const addParticipant = useCallback(\n async (conversationId: string, userId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/participants`,\n {\n method: 'POST',\n headers: authHeaders(),\n body: JSON.stringify({ user_id: userId }),\n }\n );\n\n if (!response.ok) {\n throw { code: 'ADD_PARTICIPANT_ERROR', message: 'Failed to add participant' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const removeParticipant = useCallback(\n async (conversationId: string, userId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/participants/${userId}`,\n {\n method: 'DELETE',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n throw { code: 'REMOVE_PARTICIPANT_ERROR', message: 'Failed to remove participant' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Conversation list (Inbox) ──────────────────────────────────────────\n\n const fetchConversationList = useCallback(async (): Promise<ConversationListItem[]> => {\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/conversations`, {\n headers: authHeaders(),\n });\n\n if (!response.ok) {\n throw { code: 'LIST_ERROR', message: 'Failed to fetch conversation list' };\n }\n\n return snakeToCamel(await response.json());\n }, [apiBaseUrl, authHeaders]);\n\n // ── Pin management ──────────────────────────────────────────\n\n const pinMessage = useCallback(\n async (conversationId: string, messageId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages/${messageId}/pin`,\n {\n method: 'POST',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw { code: 'PIN_ERROR', message: 'Failed to pin message', details: error };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const unpinMessage = useCallback(\n async (conversationId: string, messageId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages/${messageId}/pin`,\n {\n method: 'DELETE',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n throw { code: 'UNPIN_ERROR', message: 'Failed to unpin message' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const fetchPinnedMessages = useCallback(\n async (conversationId: string): Promise<Message[]> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/pinned`,\n { headers: authHeaders() }\n );\n\n if (!response.ok) {\n throw { code: 'FETCH_PINNED_ERROR', message: 'Failed to fetch pinned messages' };\n }\n\n return snakeToCamel(await response.json());\n },\n [apiBaseUrl, authHeaders]\n );\n\n const totalUnread = Object.values(unreadCounts).reduce((sum, count) => sum + count, 0);\n\n if (!socket) return null;\n\n return (\n <CollabContext.Provider\n value={{\n socket,\n config,\n apiBaseUrl,\n totalUnread,\n unreadCounts,\n requestPreview,\n invalidatePreview,\n fetchMessages,\n createConversationWithMessage,\n addParticipant,\n removeParticipant,\n fetchConversationList,\n pinMessage,\n unpinMessage,\n fetchPinnedMessages,\n }}\n >\n {children}\n </CollabContext.Provider>\n );\n}\n","import type { PatientData } from './types';\n\n/**\n * Canonical channel name format, used both when creating conversations\n * and wherever a channel needs to be labeled in the UI.\n *\n * Format: `<patient> - <lab> - <last 4 of order id>`\n * Example: \"John Doe - Beachside Lab - 1189\"\n *\n * If `labName` is missing (host order didn't carry lab info) the lab\n * segment is dropped instead of rendered as an empty `\" - - \"`. The\n * `cleanChannelName` helper applies the same collapse to strings that\n * arrived from the server (older conversations may have been persisted\n * with the empty segment baked in).\n */\nexport function buildChannelName(patientData: PatientData): string {\n const patientPart = patientData.patientName?.trim() || 'Unknown';\n const labPart = patientData.labName?.trim()?.slice(0, 24) || '';\n const last4 = (patientData.displayOrderId ?? '').trim().slice(-4) || '0000';\n return labPart\n ? `${patientPart} - ${labPart} - ${last4}`\n : `${patientPart} - ${last4}`;\n}\n\n/**\n * Collapse the empty-lab segment from a server-stored channel name.\n *\n * Pre-fix, the package would persist `conversation.name` as\n * `\"Patient - - 1234\"` whenever the host omitted labName. Those records\n * still exist in the DB. Run server-supplied names through here before\n * rendering so the empty middle segment doesn't leak into the UI.\n */\nexport function cleanChannelName(name: string | undefined | null): string {\n if (!name) return '';\n // Collapse \"<x> - - <y>\" (any whitespace between the two dashes) to\n // \"<x> - <y>\". Tolerates both single and double-space middles.\n return name.replace(/\\s+-\\s+-\\s+/g, ' - ').trim();\n}\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n Message,\n Participant,\n Conversation,\n SendMessagePayload,\n TypingEvent,\n PatientData,\n} from '../core/types';\nimport { buildChannelName } from '../core/channelName';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\n\ninterface UseConversationOptions {\n orderId: string;\n patientData: PatientData;\n /** Participant user IDs used only when creating a brand-new conversation */\n participantIds?: string[];\n /** Load full history on mount (default true) */\n loadHistory?: boolean;\n}\n\ninterface UseConversationReturn {\n conversation: Conversation | null;\n messages: Message[];\n pinnedMessages: Message[];\n participants: Participant[];\n typingUsers: TypingEvent[];\n isLoading: boolean;\n hasMore: boolean;\n error: string | null;\n isConnected: boolean;\n /** Message currently being replied to (null if not replying) */\n replyTo: Message | null;\n /** Set/clear the active reply target */\n setReplyTo: (message: Message | null) => void;\n sendMessage: (body: string) => Promise<void>;\n /** Re-attempt sending a previously-failed optimistic text message */\n retryMessage: (messageId: string) => Promise<void>;\n sendAudioMessage: (audioBlob: Blob, duration: number) => Promise<void>;\n sendFileMessage: (file: File) => Promise<void>;\n sendDeepLink: (path: string, label: string) => Promise<void>;\n sendTyping: (isTyping: boolean) => void;\n markAsRead: (messageId: string) => void;\n loadMoreMessages: () => Promise<void>;\n pinMessage: (messageId: string) => Promise<void>;\n unpinMessage: (messageId: string) => Promise<void>;\n}\n\n/**\n * Full conversation hook used by CollabPanel / CollabPopup.\n *\n * Lazy creation: the conversation is NOT created on mount. It's only created\n * when the user sends the first message. If a conversation already exists for\n * the given orderId, it's loaded and joined automatically.\n */\nexport function useConversation({\n orderId,\n patientData,\n participantIds = [],\n loadHistory = true,\n}: UseConversationOptions): UseConversationReturn {\n const {\n socket,\n config,\n requestPreview,\n invalidatePreview,\n fetchMessages,\n createConversationWithMessage,\n pinMessage: pinMessageApi,\n unpinMessage: unpinMessageApi,\n } = useCollab();\n\n const [conversation, setConversation] = useState<Conversation | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const [pinnedMessages, setPinnedMessages] = useState<Message[]>([]);\n const [participants, setParticipants] = useState<Participant[]>([]);\n const [typingUsers, setTypingUsers] = useState<TypingEvent[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [replyTo, setReplyTo] = useState<Message | null>(null);\n\n const joinedConversationId = useRef<string | null>(null);\n const typingTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n // In-flight promise for the lazy-create call. Two sends hitting before\n // state updates would each see `conversation: null` and POST twice; with\n // this guard, the second caller awaits the first's result instead.\n const ensureConversationInFlight = useRef<Promise<Conversation> | null>(null);\n // Messages we've already sent a `message:read` push for, in this session.\n // The MessageList's IntersectionObserver refires on every messages[] state\n // change; without this dedupe, every broadcast-driven readBy update\n // retriggers mark-read on every visible row, causing a runaway loop.\n const markedReadIdsRef = useRef<Set<string>>(new Set());\n\n // Build the canonical channel name at create time. If the host's\n // patientData doesn't carry a labName AND the current user is a lab,\n // fall back to their userName β€” that's the common \"lab user starts a\n // chat on their own order\" path, and without this fallback the\n // conversation gets persisted server-side with an empty lab segment.\n const buildName = useCallback(\n (): string => {\n const labName =\n patientData.labName ??\n (config.userRole === 'lab' ? config.userName : undefined);\n return buildChannelName({ ...patientData, labName });\n },\n [patientData, config.userRole, config.userName]\n );\n\n const joinChannel = useCallback(\n (conv: Conversation) => {\n if (joinedConversationId.current === conv.id) return;\n\n socket.joinConversation(conv.id, {\n // Dedupe by id so an optimistic message (added client-side on send)\n // doesn't double up when the server's broadcast arrives.\n onMessage: (msg) =>\n setMessages((prev) => {\n if (prev.some((m) => m.id === msg.id)) return prev;\n // Replace any optimistic twin (same sender, same body, still pending).\n const optimisticIdx = prev.findIndex(\n (m) =>\n m.id.startsWith('pending-') &&\n m.senderId === msg.senderId &&\n m.body === msg.body\n );\n if (optimisticIdx >= 0) {\n const next = prev.slice();\n next[optimisticIdx] = msg;\n return next;\n }\n return [...prev, msg];\n }),\n onTyping: (event) => {\n if (event.userId === config.userId) return;\n\n if (event.isTyping) {\n setTypingUsers((prev) => {\n const exists = prev.some((t) => t.userId === event.userId);\n return exists ? prev : [...prev, event];\n });\n const existingTimer = typingTimers.current.get(event.userId);\n if (existingTimer) clearTimeout(existingTimer);\n const timer = setTimeout(() => {\n setTypingUsers((prev) => prev.filter((t) => t.userId !== event.userId));\n typingTimers.current.delete(event.userId);\n }, 3000);\n typingTimers.current.set(event.userId, timer);\n } else {\n setTypingUsers((prev) => prev.filter((t) => t.userId !== event.userId));\n const timer = typingTimers.current.get(event.userId);\n if (timer) clearTimeout(timer);\n typingTimers.current.delete(event.userId);\n }\n },\n onUserJoined: (participant) => {\n setParticipants((prev) =>\n prev.some((p) => p.userId === participant.userId) ? prev : [...prev, participant]\n );\n },\n onUserLeft: (participant) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== participant.userId));\n },\n onChannelUpdated: (updates) => {\n setConversation((prev) => (prev ? { ...prev, ...updates } : prev));\n },\n onChannelDeleted: () => {\n setConversation(null);\n setMessages([]);\n joinedConversationId.current = null;\n setIsConnected(false);\n },\n onMessageRead: ({ messageId, userId }) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === messageId && !(msg.readBy ?? []).includes(userId)\n ? { ...msg, readBy: [...(msg.readBy ?? []), userId] }\n : msg\n )\n );\n },\n onMessagePinned: (message) => {\n setPinnedMessages((prev) =>\n prev.some((m) => m.id === message.id) ? prev : [...prev, message]\n );\n setMessages((prev) =>\n prev.map((m) => (m.id === message.id ? { ...m, isPinned: true } : m))\n );\n },\n onMessageUnpinned: ({ messageId }) => {\n setPinnedMessages((prev) => prev.filter((m) => m.id !== messageId));\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, isPinned: false } : m))\n );\n },\n });\n\n joinedConversationId.current = conv.id;\n setIsConnected(true);\n },\n [socket, config.userId]\n );\n\n // Initial load: check for existing conversation via preview\n useEffect(() => {\n let cancelled = false;\n\n const init = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const preview = await requestPreview(orderId);\n\n if (cancelled) return;\n\n if (!preview) {\n // No conversation exists yet β€” stay in \"new\" mode\n setConversation(null);\n setMessages([]);\n setParticipants([]);\n setHasMore(false);\n setIsLoading(false);\n return;\n }\n\n const existingConv: Conversation = {\n id: preview.conversationId,\n orderId: preview.orderId,\n name: preview.name,\n participants: preview.participants,\n unreadCount: preview.unreadCount,\n createdAt: '',\n updatedAt: '',\n };\n\n setConversation(existingConv);\n setParticipants(preview.participants);\n // Channel join kicks off synchronously (Phoenix push handles the\n // async part). Renders can proceed while the join completes.\n joinChannel(existingConv);\n\n // Skip preview.lastMessages as the initial paint β€” that two-wave\n // pattern (preview β†’ history merge) was prepending older messages\n // after MessageList had already done its initial scroll, stranding\n // the user mid-thread. Wait for fetchMessages so we paint once,\n // with the full first page, and the scroll lands correctly on the\n // first try. The preview is still used above for conversation\n // metadata (id, name, participants) and over in the inbox row's\n // last-message blurb β€” just not as the initial message list state\n // here.\n if (loadHistory) {\n fetchMessages(preview.conversationId)\n .then((history) => {\n if (cancelled) return;\n setMessages(history);\n setHasMore(history.length >= MESSAGES_PAGE_SIZE);\n setPinnedMessages(history.filter((m) => m.isPinned));\n setIsLoading(false);\n })\n .catch(() => {\n if (cancelled) return;\n // fetchMessages surfaces the error via onError. Drop the\n // loading state so the panel doesn't hang on a stuck spinner;\n // the user can still send a new message (which doesn't\n // depend on the historical fetch).\n setIsLoading(false);\n });\n } else {\n // Caller explicitly opted out of history; paint empty and let\n // socket-driven new messages stream in.\n setMessages([]);\n setHasMore(false);\n setPinnedMessages([]);\n setIsLoading(false);\n }\n } catch (err) {\n if (cancelled) return;\n const msg = err instanceof Error ? err.message : 'Failed to load conversation';\n setError(msg);\n setIsLoading(false);\n }\n };\n\n init();\n\n return () => {\n cancelled = true;\n if (joinedConversationId.current) {\n socket.leaveConversation(joinedConversationId.current);\n joinedConversationId.current = null;\n }\n typingTimers.current.forEach((timer) => clearTimeout(timer));\n typingTimers.current.clear();\n markedReadIdsRef.current.clear();\n setIsConnected(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [orderId]);\n\n // ── Send helpers ──\n\n // `persistedByCreate` tells the caller whether THEIR payload was written\n // by the REST create (true = don't also send via socket, that would dup).\n // - conversation already existed β†’ false\n // - piggy-backed on someone else's in-flight create β†’ false (their payload\n // needs a socket send)\n // - this caller kicked off the create β†’ true (their payload was in the POST)\n const ensureConversation = useCallback(\n async (\n payload: SendMessagePayload\n ): Promise<{ conv: Conversation; persistedByCreate: boolean }> => {\n if (conversation) return { conv: conversation, persistedByCreate: false };\n\n if (ensureConversationInFlight.current) {\n const conv = await ensureConversationInFlight.current;\n return { conv, persistedByCreate: false };\n }\n\n const inflight = (async () => {\n const result = await createConversationWithMessage(orderId, payload, {\n name: buildName(),\n participantIds,\n });\n\n setConversation(result.conversation);\n setParticipants(result.conversation.participants);\n setMessages([result.message]);\n joinChannel(result.conversation);\n invalidatePreview(orderId);\n\n // Create-or-send may have appended our message to an EXISTING\n // study-scoped conversation with prior history β€” the init effect's\n // preview-backed load doesn't cover that case because `conversation`\n // was null when it ran. Pull authoritative history now and merge\n // (dedupe by id so the just-inserted message isn't duplicated).\n if (loadHistory) {\n fetchMessages(result.conversation.id)\n .then((history) => {\n setMessages((prev) => {\n const seen = new Set(prev.map((m) => m.id));\n const older = history.filter((m) => !seen.has(m.id));\n return [...older, ...prev];\n });\n setPinnedMessages((prev) => {\n const fromHistory = history.filter((m) => m.isPinned);\n const seen = new Set(prev.map((m) => m.id));\n return [...fromHistory.filter((m) => !seen.has(m.id)), ...prev];\n });\n })\n .catch(() => {\n // Non-fatal β€” fetchMessages already surfaces via onError.\n });\n }\n\n return result.conversation;\n })();\n\n ensureConversationInFlight.current = inflight;\n\n try {\n const conv = await inflight;\n return { conv, persistedByCreate: true };\n } finally {\n ensureConversationInFlight.current = null;\n }\n },\n [\n conversation,\n createConversationWithMessage,\n orderId,\n buildName,\n participantIds,\n joinChannel,\n invalidatePreview,\n loadHistory,\n fetchMessages,\n ]\n );\n\n const sendMessage = useCallback(\n async (body: string) => {\n const payload: SendMessagePayload = {\n body,\n type: 'text',\n ...(replyTo ? { reply_to_id: replyTo.id } : {}),\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n setReplyTo(null);\n\n // Our message was already written by the REST create β€” skip the socket\n // push, otherwise we'd persist the same message twice.\n if (persistedByCreate) return;\n\n // Optimistic insert so the user sees their text instantly, regardless\n // of socket roundtrip. The server broadcast (via onMessage above) will\n // swap this in for the real, persisted message.\n const optimistic: Message = {\n id: `pending-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n conversationId: conv.id,\n senderId: config.userId,\n senderName: config.userName,\n senderRole: config.userRole,\n body,\n type: 'text',\n insertedAt: new Date().toISOString(),\n status: 'sending',\n ...(replyTo\n ? {\n replyToId: replyTo.id,\n replyToSnapshot: {\n messageId: replyTo.id,\n senderId: replyTo.senderId,\n senderName: replyTo.senderName,\n body: replyTo.body,\n type: replyTo.type,\n },\n }\n : {}),\n };\n setMessages((prev) => [...prev, optimistic]);\n\n try {\n await socket.sendMessage(conv.id, payload);\n } catch (err) {\n // Keep the bubble in place but flip its status so the user sees\n // \"Failed\" + a Retry affordance instead of the message silently\n // vanishing. If the server actually persisted and broadcasts the\n // same message later, the onMessage twin-match below will swap\n // this row out naturally.\n setMessages((prev) =>\n prev.map((m) => (m.id === optimistic.id ? { ...m, status: 'failed' as const } : m))\n );\n config.onError?.({\n code: 'SEND_FAILED',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [ensureConversation, socket, replyTo, config]\n );\n\n const retryMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n const target = messages.find((m) => m.id === messageId);\n if (!target || target.status !== 'failed' || target.type !== 'text') return;\n\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, status: 'sending' as const } : m))\n );\n\n const payload: SendMessagePayload = {\n body: target.body,\n type: 'text',\n ...(target.replyToId ? { reply_to_id: target.replyToId } : {}),\n };\n\n try {\n await socket.sendMessage(conversation.id, payload);\n } catch (err) {\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, status: 'failed' as const } : m))\n );\n config.onError?.({\n code: 'SEND_FAILED',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [conversation, messages, socket, config]\n );\n\n const sendAudioMessage = useCallback(\n async (audioBlob: Blob, duration: number) => {\n if (!config.onUploadFile) return;\n const url = await config.onUploadFile(audioBlob, 'voice-message.webm');\n const payload: SendMessagePayload = {\n body: 'Voice message',\n type: 'audio',\n media_url: url,\n media_duration: duration,\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [config, ensureConversation, socket]\n );\n\n const sendFileMessage = useCallback(\n async (file: File) => {\n if (!config.onUploadFile) return;\n const url = await config.onUploadFile(file, file.name);\n const isImage = file.type.startsWith('image/');\n const payload: SendMessagePayload = {\n body: file.name,\n type: isImage ? 'image' : 'file',\n media_url: url,\n file_name: file.name,\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [config, ensureConversation, socket]\n );\n\n const sendDeepLink = useCallback(\n async (path: string, label: string) => {\n const payload: SendMessagePayload = {\n body: label,\n type: 'deep_link',\n metadata: { path },\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [ensureConversation, socket]\n );\n\n const sendTypingIndicator = useCallback(\n (isTyping: boolean) => {\n if (!conversation || !isConnected) return;\n socket.sendTyping(conversation.id, isTyping);\n },\n [conversation, isConnected, socket]\n );\n\n const markAsRead = useCallback(\n (messageId: string) => {\n if (!conversation || !isConnected) return;\n if (markedReadIdsRef.current.has(messageId)) return;\n markedReadIdsRef.current.add(messageId);\n socket.markAsRead(conversation.id, messageId);\n },\n [conversation, isConnected, socket]\n );\n\n const loadMoreMessages = useCallback(async () => {\n if (!conversation || !hasMore || isLoading) return;\n\n const oldestMessage = messages[0];\n const before = oldestMessage?.id;\n\n setIsLoading(true);\n try {\n const older = await fetchMessages(conversation.id, { before });\n setMessages((prev) => [...older, ...prev]);\n setHasMore(older.length > 0);\n } catch (err) {\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load older messages',\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [conversation, hasMore, isLoading, messages, fetchMessages, config]);\n\n const pinMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n try {\n await pinMessageApi(conversation.id, messageId);\n } catch (err) {\n config.onError?.({\n code: 'PIN_ERROR',\n message: 'Failed to pin message',\n details: err,\n });\n throw err;\n }\n },\n [conversation, pinMessageApi, config]\n );\n\n const unpinMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n try {\n await unpinMessageApi(conversation.id, messageId);\n } catch (err) {\n config.onError?.({\n code: 'UNPIN_ERROR',\n message: 'Failed to unpin message',\n details: err,\n });\n throw err;\n }\n },\n [conversation, unpinMessageApi, config]\n );\n\n return {\n conversation,\n messages,\n pinnedMessages,\n participants,\n typingUsers,\n isLoading,\n hasMore,\n error,\n isConnected,\n replyTo,\n setReplyTo,\n sendMessage,\n retryMessage,\n sendAudioMessage,\n sendFileMessage,\n sendDeepLink,\n sendTyping: sendTypingIndicator,\n markAsRead,\n loadMoreMessages,\n pinMessage,\n unpinMessage,\n };\n}\n","import { useCallback, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n ChannelUpdatePayload,\n InviteUserPayload,\n CollabError,\n} from '../core/types';\n\ninterface UseChannelSettingsOptions {\n conversationId: string | null;\n}\n\ninterface UseChannelSettingsReturn {\n /** Invite a user to the conversation */\n inviteUser: (payload: InviteUserPayload) => Promise<void>;\n /** Remove a user from the conversation (admin/creator only) */\n removeUser: (userId: string) => Promise<void>;\n /** Current user leaves the conversation */\n leaveChannel: () => Promise<void>;\n /** Delete the conversation entirely (admin only) */\n deleteChannel: () => Promise<void>;\n /** Update channel name and/or picture */\n updateChannel: (payload: ChannelUpdatePayload) => Promise<void>;\n /** Whether an operation is in progress */\n isUpdating: boolean;\n /** Last error from any operation */\n error: CollabError | null;\n /** Whether current user can perform admin actions */\n isAdmin: boolean;\n}\n\nexport function useChannelSettings({ conversationId }: UseChannelSettingsOptions): UseChannelSettingsReturn {\n const { socket, config } = useCollab();\n const [isUpdating, setIsUpdating] = useState(false);\n const [error, setError] = useState<CollabError | null>(null);\n\n const isAdmin = config.userRole === 'admin';\n\n const withLoading = useCallback(\n async <T>(operation: () => Promise<T>): Promise<T | undefined> => {\n if (!conversationId) return;\n setIsUpdating(true);\n setError(null);\n try {\n const result = await operation();\n setIsUpdating(false);\n return result;\n } catch (err) {\n const collabError: CollabError =\n typeof err === 'object' && err !== null && 'code' in err\n ? (err as CollabError)\n : { code: 'UNKNOWN', message: 'Operation failed' };\n\n setError(collabError);\n setIsUpdating(false);\n config.onError?.(collabError);\n return undefined;\n }\n },\n [conversationId, config]\n );\n\n const inviteUser = useCallback(\n async (payload: InviteUserPayload) => {\n await withLoading(() => socket.inviteUser(conversationId!, payload));\n },\n [conversationId, socket, withLoading]\n );\n\n const removeUser = useCallback(\n async (userId: string) => {\n await withLoading(() => socket.removeUser(conversationId!, userId));\n },\n [conversationId, socket, withLoading]\n );\n\n const leaveChannel = useCallback(async () => {\n await withLoading(async () => {\n await socket.removeUser(conversationId!, config.userId);\n socket.leaveConversation(conversationId!);\n });\n }, [conversationId, socket, config.userId, withLoading]);\n\n const deleteChannel = useCallback(async () => {\n if (!isAdmin) {\n const err: CollabError = {\n code: 'FORBIDDEN',\n message: 'Only admins can delete channels',\n };\n setError(err);\n config.onError?.(err);\n return;\n }\n await withLoading(() => socket.deleteChannel(conversationId!));\n }, [conversationId, socket, isAdmin, config, withLoading]);\n\n const updateChannel = useCallback(\n async (payload: ChannelUpdatePayload) => {\n await withLoading(() => socket.updateChannel(conversationId!, payload));\n },\n [conversationId, socket, withLoading]\n );\n\n return {\n inviteUser,\n removeUser,\n leaveChannel,\n deleteChannel,\n updateChannel,\n isUpdating,\n error,\n isAdmin,\n };\n}\n","import { useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport { DEEP_LINK_PREFIX } from '../core/constants';\n\ninterface ParsedDeepLink {\n /** Full original link string */\n raw: string;\n /** The path after natoe:// (e.g. \"order/4521\") */\n path: string;\n /** The resource type (e.g. \"order\", \"report\", \"dicom\", \"study\") */\n resource: string;\n /** The resource ID */\n id: string;\n}\n\ninterface UseDeepLinksReturn {\n /** Parse a deep link string into structured data */\n parseDeepLink: (link: string) => ParsedDeepLink | null;\n /** Handle a deep link click β€” calls config.onDeepLink or config.onOpenDicom */\n handleDeepLink: (link: string) => void;\n /** Check if a string contains deep links */\n containsDeepLink: (text: string) => boolean;\n /** Extract all deep links from a message body */\n extractDeepLinks: (text: string) => ParsedDeepLink[];\n}\n\n/**\n * Parses and handles natoe:// deep links in messages.\n *\n * Supported formats:\n * natoe://order/4521 β†’ opens order detail\n * natoe://report/4521 β†’ opens report\n * natoe://dicom/4521 β†’ opens DICOM viewer (uses onOpenDicom callback)\n * natoe://study/4521 β†’ opens study detail\n */\nexport function useDeepLinks(): UseDeepLinksReturn {\n const { config } = useCollab();\n\n const parseDeepLink = useCallback((link: string): ParsedDeepLink | null => {\n if (!link.startsWith(DEEP_LINK_PREFIX)) return null;\n\n const path = link.slice(DEEP_LINK_PREFIX.length);\n const parts = path.split('/').filter(Boolean);\n\n if (parts.length < 2) return null;\n\n return {\n raw: link,\n path,\n resource: parts[0],\n id: parts[1],\n };\n }, []);\n\n const handleDeepLink = useCallback(\n (link: string) => {\n const parsed = parseDeepLink(link);\n if (!parsed) return;\n\n // DICOM links use the dedicated callback\n if (parsed.resource === 'dicom' && config.onOpenDicom) {\n config.onOpenDicom(parsed.id, '');\n return;\n }\n\n // Everything else goes through the generic deep link handler\n if (config.onDeepLink) {\n config.onDeepLink(parsed.path);\n }\n },\n [parseDeepLink, config]\n );\n\n const containsDeepLink = useCallback((text: string): boolean => {\n return text.includes(DEEP_LINK_PREFIX);\n }, []);\n\n const extractDeepLinks = useCallback(\n (text: string): ParsedDeepLink[] => {\n // Match natoe://path/segments patterns in text\n const regex = new RegExp(`${escapeRegex(DEEP_LINK_PREFIX)}[\\\\w/.-]+`, 'g');\n const matches = text.match(regex) || [];\n return matches.map(parseDeepLink).filter((link): link is ParsedDeepLink => link !== null);\n },\n [parseDeepLink]\n );\n\n return {\n parseDeepLink,\n handleDeepLink,\n containsDeepLink,\n extractDeepLinks,\n };\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import React from 'react';\n\n/**\n * \"Stack of slices\" glyph standing in for a DICOM study β€” three offset\n * rectangles to convey series/imaging without leaning on a specific anatomy.\n */\nexport function DicomIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"4\" y=\"4\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M7 7h13a2 2 0 0 1 2 2v11\" opacity=\"0.6\" />\n <circle cx=\"9\" cy=\"9.5\" r=\"1.2\" fill={color} stroke=\"none\" />\n <path d=\"M5 14l3-3 4 4 2-2 3 3\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function SettingsIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function BackIcon({ size = 22, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\" />\n </svg>\n );\n}\n","import React from 'react';\nimport { buildChannelName, cleanChannelName } from '../core/channelName';\nimport { DicomIcon } from './icons/DicomIcon';\nimport { SettingsIcon } from './icons/SettingsIcon';\nimport { BackIcon } from './icons/BackIcon';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SIZE,\n SPACE,\n} from '../core/theme';\nimport type { PatientData, Participant } from '../core/types';\n\ninterface PatientHeaderProps {\n patientData: PatientData;\n participants: Participant[];\n onOpenDicom?: () => void;\n onOpenSettings?: () => void;\n /** When set, renders a back-arrow button (compact inbox returning to list) */\n onBack?: () => void;\n /** Suppress the channel name row β€” use when the name is already shown in a parent title bar */\n hideName?: boolean;\n /** Override the displayed name β€” use the stored conversation.name to avoid reconstructing from patientData components */\n displayName?: string;\n className?: string;\n}\n\ninterface MetaItem {\n /** Stable key per slot (the field name), so React can dedupe even if\n * two unrelated slots happen to have the same value. */\n key: string;\n /** Uppercase label that sits above the value (\"AGE / SEX\", \"LAB\"). */\n label: string;\n /** The rendered value (\"54 Β· M\", \"Beachside Lab\", \"Knee\"). */\n value: string;\n}\n\n/**\n * Pick the most trustworthy name to show in the header.\n *\n * When `patientData` carries both labName and displayOrderId, the locally\n * built \"<patient> - <lab> - <last4>\" is guaranteed complete (CollabInbox's\n * buildPatientData merges these in from the inbox row's canonical name).\n * In that case prefer it over the server-supplied `displayName` β€” that way\n * the chat header always matches the string the user just clicked on in the\n * inbox, even if the backend's preview endpoint happens to return a less\n * complete `conversation.name` than the list endpoint did.\n *\n * Otherwise (e.g. host passed a stub PatientData without lab info), trust\n * the server's `displayName` if present, falling back to whatever the local\n * builder can manage.\n */\nfunction resolveDisplayName(patientData: PatientData, displayName?: string): string {\n const localComplete = !!patientData.labName && !!patientData.displayOrderId;\n if (localComplete) return buildChannelName(patientData);\n // Server-supplied names from older conversations may have been persisted\n // with an empty lab segment (\"Patient - - 1234\"). Collapse those before\n // rendering so the empty middle doesn't leak into the UI.\n return cleanChannelName(displayName) || buildChannelName(patientData);\n}\n\n/**\n * \"Case card\" header that sits below the window title bar. Tinted blue-50\n * background to set it apart from the conversation body. Renders a row\n * of labelled key-value columns (label uppercase on top, value below) for\n * the clinical context the host passed in, with the action buttons\n * (View DICOM + Settings) right-aligned.\n *\n * Used in two layouts:\n * - Popup path (`hideName=true`): the surrounding title bar already\n * shows the patient name, so we render the case card only.\n * - Compact-inbox path (`hideName=false`): the panel is a full-page\n * experience and there's no outer title, so we still show the name +\n * back button stacked above the case card.\n */\nexport function PatientHeader({\n patientData,\n onOpenDicom,\n onOpenSettings,\n onBack,\n hideName = false,\n displayName,\n className,\n}: PatientHeaderProps) {\n const hasDicom = !!(patientData.studyId && patientData.storageId);\n\n const meta: MetaItem[] = [];\n // Age + Sex share one column with a centre-dot separator β€” natural\n // clinical shorthand. If only one is set, fall back to the single one.\n if (patientData.patientAge && patientData.patientSex) {\n meta.push({\n key: 'ageSex',\n label: 'Age / Sex',\n value: `${patientData.patientAge} Β· ${patientData.patientSex}`,\n });\n } else if (patientData.patientAge) {\n meta.push({ key: 'age', label: 'Age', value: String(patientData.patientAge) });\n } else if (patientData.patientSex) {\n meta.push({ key: 'sex', label: 'Sex', value: String(patientData.patientSex) });\n }\n if (patientData.studyType) {\n meta.push({ key: 'modality', label: 'Modality', value: patientData.studyType });\n }\n if (patientData.bodyParts && patientData.bodyParts.length > 0) {\n meta.push({\n key: 'body',\n label: 'Body part',\n value: patientData.bodyParts.join(', '),\n });\n }\n // Referring physician deliberately omitted from the case card β€” kept\n // off the chat surface to reduce visual density. Still available in\n // the order detail view.\n\n const hasActions = (hasDicom && onOpenDicom) || onOpenSettings;\n\n return (\n <div className={className} style={styles.container}>\n {!hideName && (\n <div style={styles.nameRow}>\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n style={styles.backButton}\n aria-label=\"Back to conversations\"\n title=\"Back to conversations\"\n >\n <BackIcon size={22} color={COLOR.neutral800} />\n </button>\n )}\n <span style={styles.nameText}>{resolveDisplayName(patientData, displayName)}</span>\n </div>\n )}\n\n <div style={styles.caseCard}>\n {/* Meta β€” stacked label-above-value columns flowing in a wrap-\n enabled row so they re-stack to a second row on narrow\n popups instead of overflowing horizontally. */}\n {meta.length > 0 && (\n <div style={styles.metaRow}>\n {meta.map((item) => (\n <div key={item.key} style={styles.metaCol}>\n <span style={styles.metaLabel}>{item.label}</span>\n <span style={styles.metaValue}>{item.value}</span>\n </div>\n ))}\n </div>\n )}\n\n {hasActions && (\n <div style={styles.actions}>\n {hasDicom && onOpenDicom && (\n <button\n onClick={onOpenDicom}\n style={styles.dicomButton}\n type=\"button\"\n aria-label=\"View DICOM study\"\n >\n <DicomIcon size={18} color={COLOR.primary} />\n <span>View DICOM</span>\n </button>\n )}\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n style={styles.settingsIconButton}\n type=\"button\"\n aria-label=\"Open channel settings\"\n title=\"Settings\"\n >\n <SettingsIcon size={18} color={COLOR.neutral600} />\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: COLOR.primaryBg,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n // Optional name row, only when `hideName` is false (compact-inbox path)\n nameRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S3} ${SPACE.S4} ${SPACE.S2}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n backgroundColor: COLOR.white,\n },\n backButton: {\n width: SIZE.controlIcon,\n height: SIZE.controlIcon,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: `-${SPACE.S2}`,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n nameText: {\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n color: COLOR.neutral900,\n lineHeight: LINE_HEIGHT.tight,\n letterSpacing: '-0.01em',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n // Case card: meta columns flowing in a wrap-row, actions stacked\n // below. Each meta column is a small label-above-value pair so the\n // user can scan field names quickly without a legend.\n caseCard: {\n display: 'flex',\n flexDirection: 'column',\n gap: SPACE.S3,\n padding: `${SPACE.S3} ${SPACE.S5}`,\n },\n // Wrap-row of stacked label/value columns. Compact column gap keeps\n // the row dense without crowding; row gap kicks in when columns\n // wrap to a second line on narrow popups.\n metaRow: {\n display: 'flex',\n flexWrap: 'wrap',\n columnGap: SPACE.S5,\n rowGap: SPACE.S2,\n minWidth: 0,\n },\n metaCol: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n minWidth: 0,\n },\n metaLabel: {\n fontSize: '11px',\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '0.06em',\n textTransform: 'uppercase' as const,\n color: COLOR.neutral500,\n whiteSpace: 'nowrap' as const,\n },\n metaValue: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral900,\n whiteSpace: 'nowrap' as const,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: '180px',\n },\n actions: {\n display: 'flex',\n gap: SPACE.S2,\n flexShrink: 0,\n },\n dicomButton: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n minHeight: SIZE.control,\n padding: `${SPACE.S2} 14px`,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n backgroundColor: COLOR.white,\n border: `1.5px solid ${COLOR.primary}`,\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n },\n // Settings is icon-only (40x40 tile) since it's a secondary action\n // and View DICOM already carries a label.\n settingsIconButton: {\n width: SIZE.control,\n height: SIZE.control,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.lg,\n color: COLOR.neutral600,\n cursor: 'pointer',\n flexShrink: 0,\n },\n};\n","import React from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { MessageSnapshot } from '../core/types';\n\ninterface ReplyQuoteBlockProps {\n snapshot: MessageSnapshot;\n /** True when rendered inside an own-message bubble (affects color contrast) */\n inOwnBubble?: boolean;\n /** Called when user clicks the quote β€” host can scroll to the original message */\n onClick?: (messageId: string) => void;\n className?: string;\n}\n\n/**\n * Rendered inside a MessageBubble when the message is a reply.\n * Shows a compact quote of the original message.\n */\nexport function ReplyQuoteBlock({\n snapshot,\n inOwnBubble = false,\n onClick,\n className,\n}: ReplyQuoteBlockProps) {\n // The quote must clearly differ from the bubble it sits inside, otherwise\n // the visual treatment disappears and replies read as plain messages.\n // Own bubbles use a translucent white wash on the brand-blue background;\n // others' bubbles (neutral100) get a clean white card so the quote pops.\n const baseBg = inOwnBubble ? 'rgba(255,255,255,0.22)' : COLOR.white;\n const barColor = inOwnBubble ? COLOR.white : COLOR.primary;\n const nameColor = inOwnBubble ? COLOR.white : COLOR.primary;\n const bodyColor = inOwnBubble ? 'rgba(255,255,255,0.9)' : COLOR.neutral700;\n\n const preview = renderSnapshotPreview(snapshot);\n\n return (\n <div\n className={className}\n style={{ ...styles.container, backgroundColor: baseBg }}\n onClick={() => onClick?.(snapshot.messageId)}\n role={onClick ? 'button' : undefined}\n tabIndex={onClick ? 0 : undefined}\n >\n <div style={{ ...styles.bar, backgroundColor: barColor }} />\n <div style={styles.content}>\n <span style={{ ...styles.senderName, color: nameColor }}>{snapshot.senderName}</span>\n <span style={{ ...styles.body, color: bodyColor }}>{preview}</span>\n </div>\n </div>\n );\n}\n\nfunction renderSnapshotPreview(snapshot: MessageSnapshot): string {\n switch (snapshot.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return 'πŸ“· Image';\n case 'file':\n return 'πŸ“Ž File';\n case 'deep_link':\n return `πŸ”— ${snapshot.body}`;\n default: {\n const body = snapshot.body || '';\n return body.length > 80 ? `${body.slice(0, 80)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S2}`,\n marginBottom: SPACE.S1,\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n maxWidth: '100%',\n },\n bar: {\n width: '3px',\n borderRadius: '2px',\n flexShrink: 0,\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1px',\n minWidth: 0,\n overflow: 'hidden',\n },\n senderName: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n lineHeight: LINE_HEIGHT.tight,\n },\n body: {\n fontSize: FONT_SIZE.xs,\n lineHeight: LINE_HEIGHT.tight,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n};\n","import React, { useState } from 'react';\nimport { COLOR, FONT_SIZE, FONT_WEIGHT, SPACE } from '../core/theme';\nimport type { Participant } from '../core/types';\n\ninterface SeenByIndicatorProps {\n /** User IDs who have read the message */\n readBy: string[];\n /** All participants in the conversation β€” used to resolve names */\n participants: Participant[];\n /** Current user ID (excluded from the display) */\n currentUserId: string;\n /** Message sender ID (excluded from the display) */\n senderId: string;\n className?: string;\n}\n\n/**\n * WhatsApp-style \"Seen by\" indicator shown under own messages.\n * Shows up to 3 names inline; if more, shows remainder count with a tap-to-expand.\n *\n * Only renders when the current user is the sender (seen-by on others' messages\n * is redundant β€” they obviously saw their own message).\n */\nexport function SeenByIndicator({\n readBy,\n participants,\n currentUserId,\n senderId,\n className,\n}: SeenByIndicatorProps) {\n const [expanded, setExpanded] = useState(false);\n\n // Only show on own messages\n if (senderId !== currentUserId) return null;\n\n const seenByOthers = readBy\n .filter((id) => id !== currentUserId && id !== senderId)\n .map((id) => participants.find((p) => p.userId === id))\n .filter((p): p is Participant => !!p);\n\n if (seenByOthers.length === 0) return null;\n\n const displayCount = expanded ? seenByOthers.length : Math.min(3, seenByOthers.length);\n const shown = seenByOthers.slice(0, displayCount);\n const remainder = seenByOthers.length - displayCount;\n\n return (\n <div className={className} style={styles.container}>\n <span style={styles.checkmark}>βœ“βœ“</span>\n <span style={styles.label}>Seen by {shown.map((p) => p.userName ?? 'User').join(', ')}</span>\n {remainder > 0 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n setExpanded(true);\n }}\n style={styles.moreButton}\n type=\"button\"\n >\n +{remainder}\n </button>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n marginTop: '2px',\n fontSize: FONT_SIZE.xs,\n opacity: 0.85,\n },\n checkmark: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n },\n label: {\n fontSize: FONT_SIZE.xs,\n color: 'inherit',\n },\n moreButton: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: 'inherit',\n backgroundColor: 'transparent',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n textDecoration: 'underline',\n },\n};\n","import React from 'react';\n\nexport function ReplyIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function PinIcon({ size = 14, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function CopyIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n}\n","import React from 'react';\n\n/**\n * Vertical \"more options\" glyph β€” three stacked dots. Used as the\n * always-visible trigger for the per-message actions popover.\n */\nexport function MoreIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"5\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"19\" r=\"2\" />\n </svg>\n );\n}\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ReplyIcon } from './icons/ReplyIcon';\nimport { PinIcon } from './icons/PinIcon';\nimport { CopyIcon } from './icons/CopyIcon';\nimport { MoreIcon } from './icons/MoreIcon';\nimport {\n COLOR,\n FONT_SIZE,\n RADIUS,\n SHADOW,\n SIZE,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface MessageActionsMenuProps {\n message: Message;\n onReply: (message: Message) => void;\n onPin: (messageId: string) => void;\n onUnpin: (messageId: string) => void;\n onCopy?: (text: string) => void;\n /** Whether we've hit the pin limit β€” if true, pin is disabled */\n pinDisabled?: boolean;\n /** Anchor the popover to the right edge of the trigger (use for messages on the left side of the panel) */\n anchorRight?: boolean;\n className?: string;\n}\n\n/** Pixels of breathing room kept between the menu and any viewport edge. */\nconst VIEWPORT_MARGIN = 8;\n/** Gap between the trigger and the menu when shown above or below. */\nconst TRIGGER_GAP = 4;\n\n/**\n * Self-contained \"β‹―\" trigger + popover for per-message actions. The menu is\n * rendered into a portal on document.body and positioned via getBoundingClientRect,\n * so it escapes any ancestor overflow:hidden (the floating CollabPopup\n * container) and flips above the trigger when there's no room below.\n *\n * Closes on outside-click, Escape, window resize, or scroll outside the menu.\n */\nexport function MessageActionsMenu({\n message,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n pinDisabled = false,\n anchorRight = false,\n className,\n}: MessageActionsMenuProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const isPinned = !!message.isPinned;\n const canCopy = message.type === 'text' && !!message.body;\n\n // Compute placement after open β€” measure both trigger and menu, prefer\n // below the trigger but flip up when the menu would clip the viewport bottom.\n // Horizontally we honor `anchorRight` as a preference and then clamp to\n // viewport edges so the menu never hangs off-screen on narrow surfaces\n // (e.g. the 380px floating popup).\n useLayoutEffect(() => {\n if (!isOpen) {\n setCoords(null);\n return;\n }\n const trigger = triggerRef.current;\n const menu = menuRef.current;\n if (!trigger || !menu) return;\n\n const triggerRect = trigger.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const spaceBelow = vh - triggerRect.bottom;\n const spaceAbove = triggerRect.top;\n const placeAbove =\n spaceBelow < menuRect.height + TRIGGER_GAP + VIEWPORT_MARGIN &&\n spaceAbove > spaceBelow;\n\n const top = placeAbove\n ? triggerRect.top - menuRect.height - TRIGGER_GAP\n : triggerRect.bottom + TRIGGER_GAP;\n\n const preferredLeft = anchorRight\n ? triggerRect.right - menuRect.width\n : triggerRect.left;\n const left = Math.max(\n VIEWPORT_MARGIN,\n Math.min(preferredLeft, vw - menuRect.width - VIEWPORT_MARGIN)\n );\n const clampedTop = Math.max(\n VIEWPORT_MARGIN,\n Math.min(top, vh - menuRect.height - VIEWPORT_MARGIN)\n );\n\n setCoords({ top: clampedTop, left });\n }, [isOpen, anchorRight]);\n\n // Dismissal: outside-click, Escape, window resize, scroll outside the menu.\n // The menu is portaled so it's not a descendant of the wrapper β€” outside\n // checks have to consult both the trigger and the menu nodes.\n useEffect(() => {\n if (!isOpen) return;\n\n const isInside = (node: Node | null) =>\n !!node &&\n (triggerRef.current?.contains(node) === true ||\n menuRef.current?.contains(node) === true);\n\n const handleClick = (e: MouseEvent) => {\n if (!isInside(e.target as Node)) setIsOpen(false);\n };\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n };\n const handleScroll = (e: Event) => {\n if (!isInside(e.target as Node)) setIsOpen(false);\n };\n const handleResize = () => setIsOpen(false);\n\n document.addEventListener('mousedown', handleClick);\n document.addEventListener('keydown', handleKey);\n window.addEventListener('resize', handleResize);\n // Capture-phase so we see scrolls on any ancestor of the trigger (the\n // chat list, the popup, the page) without each one needing to bubble.\n window.addEventListener('scroll', handleScroll, true);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n document.removeEventListener('keydown', handleKey);\n window.removeEventListener('resize', handleResize);\n window.removeEventListener('scroll', handleScroll, true);\n };\n }, [isOpen]);\n\n const run = (fn: () => void) => {\n setIsOpen(false);\n fn();\n };\n\n const menu = isOpen ? (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label=\"Message actions\"\n style={{\n ...styles.menu,\n // Render off-screen on first paint so we can measure before placing,\n // then snap to computed coords on the next layout pass.\n top: coords?.top ?? -9999,\n left: coords?.left ?? -9999,\n visibility: coords ? 'visible' : 'hidden',\n }}\n >\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onReply(message))}\n style={styles.item}\n >\n <ReplyIcon size={18} color={COLOR.neutral700} />\n <span>Reply</span>\n </button>\n\n {isPinned ? (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onUnpin(message.id))}\n style={styles.item}\n >\n <PinIcon size={16} color={COLOR.neutral700} />\n <span>Unpin</span>\n </button>\n ) : (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onPin(message.id))}\n disabled={pinDisabled}\n style={{\n ...styles.item,\n ...(pinDisabled ? styles.itemDisabled : {}),\n }}\n title={pinDisabled ? 'Pin limit reached (max 3)' : undefined}\n >\n <PinIcon size={16} color={COLOR.neutral700} />\n <span>{pinDisabled ? 'Pin (limit reached)' : 'Pin'}</span>\n </button>\n )}\n\n {canCopy && onCopy && (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onCopy(message.body))}\n style={styles.item}\n >\n <CopyIcon size={16} color={COLOR.neutral700} />\n <span>Copy text</span>\n </button>\n )}\n </div>\n ) : null;\n\n return (\n <div className={className} style={styles.wrapper}>\n <button\n ref={triggerRef}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsOpen((v) => !v);\n }}\n aria-label=\"Message actions\"\n aria-haspopup=\"menu\"\n aria-expanded={isOpen ? 'true' : 'false'}\n title=\"Message actions\"\n style={styles.trigger}\n >\n <MoreIcon size={18} color={COLOR.neutral600} />\n </button>\n {menu && typeof document !== 'undefined' ? createPortal(menu, document.body) : null}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n wrapper: {\n position: 'relative',\n display: 'inline-block',\n },\n // Pill-shaped trigger matching the prototype's `.nc-msg-act` style β€”\n // always visible (touch-friendly) rather than hover-only.\n trigger: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '32px',\n height: '32px',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: '999px',\n cursor: 'pointer',\n color: COLOR.neutral600,\n transition: 'background-color 120ms ease, color 120ms ease, border-color 120ms ease',\n },\n menu: {\n position: 'fixed',\n minWidth: '200px',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.lg,\n boxShadow: SHADOW.popover,\n padding: '6px',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '2px',\n // Above the floating popup (z-index dialog) but below any future modal.\n zIndex: Z_INDEX.menu,\n },\n item: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n width: '100%',\n minHeight: SIZE.control,\n padding: `10px ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral700,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n textAlign: 'left' as const,\n fontFamily: 'inherit',\n },\n itemDisabled: {\n color: COLOR.neutral400,\n cursor: 'not-allowed',\n },\n};\n","import React from 'react';\n\nexport function FileIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function AlertIcon({ size = 14, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\" />\n </svg>\n );\n}\n","import React from 'react';\nimport { COLOR } from '../core/theme';\n\ninterface SpinnerProps {\n size?: number;\n color?: string;\n thickness?: number;\n}\n\n/**\n * Lightweight indeterminate spinner β€” pure CSS, no animation library.\n * Used for \"Loading earlier messages\" and any other inline progress affordance.\n */\nexport function Spinner({ size = 16, color = COLOR.neutral500, thickness = 2 }: SpinnerProps) {\n return (\n <span\n role=\"status\"\n aria-label=\"Loading\"\n style={{\n display: 'inline-block',\n width: size,\n height: size,\n border: `${thickness}px solid ${color}33`,\n borderTopColor: color,\n borderRadius: '50%',\n animation: 'natoe-colab-spin 800ms linear infinite',\n verticalAlign: 'middle',\n }}\n />\n );\n}\n\n// Inject keyframes once per page β€” repeat insert is a no-op.\nif (typeof document !== 'undefined') {\n const existing = document.getElementById('natoe-colab-spin-keyframes');\n if (!existing) {\n const style = document.createElement('style');\n style.id = 'natoe-colab-spin-keyframes';\n style.textContent = `@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }`;\n document.head.appendChild(style);\n }\n}\n","import React from 'react';\nimport { ReplyQuoteBlock } from './ReplyQuoteBlock';\nimport { SeenByIndicator } from './SeenByIndicator';\nimport { MessageActionsMenu } from './MessageActionsMenu';\nimport { FileIcon } from './icons/FileIcon';\nimport { PinIcon } from './icons/PinIcon';\nimport { AlertIcon } from './icons/AlertIcon';\nimport { Spinner } from './Spinner';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message, Participant, UserRole } from '../core/types';\nimport { DEEP_LINK_PREFIX } from '../core/constants';\n\nconst ROLE_LABELS: Record<UserRole, string> = {\n radiologist: 'Radiologist',\n lab: 'Imaging Center',\n physician: 'Physician',\n admin: 'Admin',\n};\n\ninterface MessageBubbleProps {\n message: Message;\n isOwn: boolean;\n /** Participants list β€” needed for SeenByIndicator */\n participants?: Participant[];\n /** Current user ID β€” needed for SeenByIndicator */\n currentUserId?: string;\n /** Show \"seen by\" indicator under own messages (default true β€” inline disables this) */\n showSeenBy?: boolean;\n onDeepLinkClick?: (link: string) => void;\n onReply?: (message: Message) => void;\n onPin?: (messageId: string) => void;\n onUnpin?: (messageId: string) => void;\n onCopy?: (text: string) => void;\n onReplyJumpTo?: (messageId: string) => void;\n /** Re-send a previously-failed message (own bubbles only) */\n onRetry?: (messageId: string) => void;\n /** True if pin limit reached β€” disables pin action */\n pinDisabled?: boolean;\n className?: string;\n}\n\nexport function MessageBubble({\n message,\n isOwn,\n participants = [],\n currentUserId = '',\n showSeenBy = true,\n onDeepLinkClick,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n onReplyJumpTo,\n onRetry,\n pinDisabled = false,\n className,\n}: MessageBubbleProps) {\n if (message.type === 'system') {\n return <SystemBubble message={message} />;\n }\n\n const hasActions = !!(onReply || onPin || onUnpin || onCopy);\n const actionsSlot = hasActions ? (\n <div style={styles.actionsSlot}>\n <MessageActionsMenu\n message={message}\n onReply={onReply ?? (() => {})}\n onPin={onPin ?? (() => {})}\n onUnpin={onUnpin ?? (() => {})}\n onCopy={onCopy}\n pinDisabled={pinDisabled}\n anchorRight={!isOwn}\n />\n </div>\n ) : null;\n\n return (\n <div\n className={className}\n style={{\n ...styles.wrapper,\n justifyContent: isOwn ? 'flex-end' : 'flex-start',\n }}\n >\n {isOwn && actionsSlot}\n <div style={styles.bubbleWrapper}>\n {/* Author row above the bubble (only for others' messages).\n The avatar leads in with its role-colored fill; the bubble\n sits directly below, sharing the same left edge as the\n avatar β€” a cleaner ownership cue than baking the sender\n name inside the bubble itself. */}\n {!isOwn && (\n <div style={styles.authorRow}>\n <span\n style={{\n ...styles.authorAvatar,\n backgroundColor: roleColor(message.senderRole),\n }}\n aria-hidden=\"true\"\n >\n {computeInitials(message.senderName)}\n </span>\n <span style={styles.authorName}>{message.senderName}</span>\n <RoleBadge role={message.senderRole} />\n </div>\n )}\n\n <div\n style={{\n ...styles.bubble,\n ...(isOwn ? styles.ownBubble : styles.otherBubble),\n }}\n >\n {/* Pinned indicator */}\n {message.isPinned && (\n <div\n style={{\n ...styles.pinnedBadge,\n ...(isOwn ? styles.pinnedBadgeOwn : styles.pinnedBadgeOther),\n }}\n >\n <PinIcon size={12} />\n <span>Pinned</span>\n </div>\n )}\n\n {/* Reply quote (when this message is a reply) */}\n {message.replyToSnapshot && (\n <ReplyQuoteBlock\n snapshot={message.replyToSnapshot}\n inOwnBubble={isOwn}\n onClick={onReplyJumpTo}\n />\n )}\n\n {/* Message content by type */}\n {message.type === 'text' && <TextContent body={message.body} onDeepLinkClick={onDeepLinkClick} />}\n {message.type === 'audio' && <AudioContent mediaUrl={message.mediaUrl} duration={message.mediaDuration} />}\n {message.type === 'image' && <ImageContent mediaUrl={message.mediaUrl} fileName={message.fileName} />}\n {message.type === 'file' && <FileContent mediaUrl={message.mediaUrl} fileName={message.fileName} />}\n {message.type === 'deep_link' && (\n <DeepLinkContent body={message.body} metadata={message.metadata} onDeepLinkClick={onDeepLinkClick} />\n )}\n\n {/* Footer: time + delivery state */}\n <div style={styles.bubbleFoot}>\n <span style={styles.timestamp}>{formatTime(message.insertedAt)}</span>\n\n {isOwn && message.status === 'sending' && (\n <span style={styles.footStatus}>\n <Spinner size={11} color=\"rgba(255,255,255,0.85)\" />\n <span>Sending…</span>\n </span>\n )}\n {isOwn && message.status === 'failed' && (\n <span style={styles.footStatusFailed}>\n <AlertIcon size={11} color=\"#fecaca\" />\n <span>Not sent</span>\n {onRetry && (\n <button\n type=\"button\"\n onClick={() => onRetry(message.id)}\n style={styles.retryButton}\n aria-label=\"Retry sending message\"\n >\n Retry\n </button>\n )}\n </span>\n )}\n {showSeenBy && isOwn && !message.status && (\n <SeenByIndicator\n readBy={message.readBy ?? []}\n participants={participants}\n currentUserId={currentUserId}\n senderId={message.senderId}\n />\n )}\n </div>\n </div>\n </div>\n {!isOwn && actionsSlot}\n </div>\n );\n}\n\nfunction computeInitials(name: string): string {\n return (\n name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((p) => p[0]?.toUpperCase() ?? '')\n .join('') || '?'\n );\n}\n\nfunction roleColor(role: UserRole): string {\n // Cool-only palette β€” keep role tags / author avatars in the blue\n // family so the chat screen reads as a single tonal range. Roles\n // stay distinguishable via tone (sky vs brand vs indigo vs slate)\n // rather than primary-color contrast (no greens / reds / purples).\n switch (role) {\n case 'radiologist':\n return '#4f46e5'; // indigo (blue-leaning)\n case 'lab':\n return '#2563eb'; // brand blue\n case 'physician':\n return '#0284c7'; // sky\n case 'admin':\n return '#64748b'; // slate (muted)\n default:\n return '#6b7280';\n }\n}\n\n// ── Sub-components ──\n\nfunction TextContent({ body, onDeepLinkClick }: { body: string; onDeepLinkClick?: (link: string) => void }) {\n if (body.includes(DEEP_LINK_PREFIX)) {\n const parts = body.split(new RegExp(`(${escapeRegex(DEEP_LINK_PREFIX)}[\\\\w/.-]+)`, 'g'));\n return (\n <p style={styles.textBody}>\n {parts.map((part, i) =>\n part.startsWith(DEEP_LINK_PREFIX) ? (\n <a\n key={i}\n onClick={(e) => {\n e.preventDefault();\n onDeepLinkClick?.(part);\n }}\n href=\"#\"\n style={styles.deepLink}\n >\n {part}\n </a>\n ) : (\n <span key={i}>{part}</span>\n )\n )}\n </p>\n );\n }\n\n return <p style={styles.textBody}>{body}</p>;\n}\n\nfunction AudioContent({ mediaUrl, duration }: { mediaUrl?: string; duration?: number }) {\n if (!mediaUrl) return null;\n\n return (\n <div style={styles.audioContainer}>\n <audio controls preload=\"metadata\" style={styles.audioPlayer}>\n <source src={mediaUrl} />\n </audio>\n {duration != null && <span style={styles.audioDuration}>{formatDuration(duration)}</span>}\n </div>\n );\n}\n\nfunction ImageContent({ mediaUrl, fileName }: { mediaUrl?: string; fileName?: string }) {\n if (!mediaUrl) return null;\n\n return (\n <a href={mediaUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <img src={mediaUrl} alt={fileName || 'Image'} style={styles.imagePreview} />\n </a>\n );\n}\n\nfunction FileContent({ mediaUrl, fileName }: { mediaUrl?: string; fileName?: string }) {\n if (!mediaUrl) return null;\n\n return (\n <a href={mediaUrl} target=\"_blank\" rel=\"noopener noreferrer\" style={styles.fileLink}>\n <FileIcon size={20} />\n <span style={styles.fileName}>{fileName || 'Download file'}</span>\n </a>\n );\n}\n\nfunction DeepLinkContent({\n body,\n metadata,\n onDeepLinkClick,\n}: {\n body: string;\n metadata?: Record<string, unknown>;\n onDeepLinkClick?: (link: string) => void;\n}) {\n const path = metadata?.path as string | undefined;\n\n return (\n <div\n style={styles.deepLinkCard}\n onClick={() => path && onDeepLinkClick?.(`${DEEP_LINK_PREFIX}${path}`)}\n >\n <span style={styles.deepLinkLabel}>{body}</span>\n {path && <span style={styles.deepLinkPath}>{DEEP_LINK_PREFIX}{path}</span>}\n </div>\n );\n}\n\nfunction SystemBubble({ message }: { message: Message }) {\n return (\n <div style={styles.systemWrapper}>\n <span style={styles.systemPill}>\n <span>{message.body}</span>\n <span style={styles.systemTime}>{formatTime(message.insertedAt)}</span>\n </span>\n </div>\n );\n}\n\nfunction RoleBadge({ role }: { role: UserRole }) {\n // Solid role-coloured pill with white text β€” keeps the same palette\n // values, just inverts the treatment from tinted-on-light to bold.\n return (\n <span style={{ ...styles.roleBadge, backgroundColor: roleColor(role) }}>\n {ROLE_LABELS[role] ?? role}\n </span>\n );\n}\n\n// ── Helpers ──\n\nfunction formatTime(iso: string): string {\n try {\n return new Date(iso).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n } catch {\n return '';\n }\n}\n\nfunction formatDuration(seconds: number): string {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// ── Styles ──\n\nconst styles: Record<string, React.CSSProperties> = {\n wrapper: {\n display: 'flex',\n alignItems: 'flex-end',\n gap: SPACE.S1,\n marginBottom: SPACE.S3,\n paddingLeft: SPACE.S4,\n paddingRight: SPACE.S4,\n },\n bubbleWrapper: {\n position: 'relative',\n maxWidth: '78%',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n },\n actionsSlot: {\n flexShrink: 0,\n alignSelf: 'flex-end',\n },\n // Author row above the bubble β€” only rendered for others' messages.\n authorRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n authorAvatar: {\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n color: COLOR.white,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.bold,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n letterSpacing: '0.02em',\n },\n authorName: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n },\n bubble: {\n padding: `${SPACE.S3} ${SPACE.S4}`,\n borderRadius: '18px',\n wordBreak: 'break-word',\n border: '1px solid transparent',\n },\n ownBubble: {\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n borderColor: COLOR.primary,\n borderBottomRightRadius: '6px',\n },\n otherBubble: {\n backgroundColor: COLOR.neutral100,\n color: COLOR.neutral900,\n borderColor: COLOR.neutral200,\n borderBottomLeftRadius: '6px',\n },\n pinnedBadge: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n fontWeight: FONT_WEIGHT.bold,\n marginBottom: SPACE.S2,\n padding: `2px ${SPACE.S2}`,\n borderRadius: '999px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n pinnedBadgeOther: {\n color: '#b8680f',\n backgroundColor: '#fff7e0',\n },\n pinnedBadgeOwn: {\n color: '#fff4d6',\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n },\n roleBadge: {\n fontSize: '10px',\n fontWeight: FONT_WEIGHT.bold,\n padding: '2px 7px',\n borderRadius: RADIUS.sm,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n color: COLOR.white,\n flexShrink: 0,\n },\n textBody: {\n margin: 0,\n fontSize: FONT_SIZE.md,\n lineHeight: 1.5,\n },\n bubbleFoot: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: SPACE.S2,\n marginTop: SPACE.S2,\n fontSize: '11px',\n opacity: 0.85,\n },\n timestamp: {\n fontSize: '11px',\n color: 'inherit',\n fontVariantNumeric: 'tabular-nums',\n },\n footStatus: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n },\n footStatusFailed: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n },\n retryButton: {\n background: 'transparent',\n border: 'none',\n color: COLOR.white,\n fontWeight: FONT_WEIGHT.semibold,\n fontSize: '11px',\n textDecoration: 'underline',\n cursor: 'pointer',\n padding: `0 ${SPACE.S1}`,\n },\n audioContainer: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n audioPlayer: {\n height: '32px',\n maxWidth: '220px',\n },\n audioDuration: {\n fontSize: FONT_SIZE.xs,\n opacity: 0.7,\n whiteSpace: 'nowrap' as const,\n },\n imagePreview: {\n maxWidth: '240px',\n maxHeight: '180px',\n borderRadius: RADIUS.md,\n objectFit: 'cover' as const,\n cursor: 'pointer',\n },\n fileLink: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n textDecoration: 'none',\n color: 'inherit',\n padding: `${SPACE.S1} 0`,\n },\n fileName: {\n fontSize: FONT_SIZE.sm,\n textDecoration: 'underline',\n },\n deepLink: {\n color: COLOR.primary,\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n deepLinkCard: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '2px',\n padding: SPACE.S2,\n backgroundColor: COLOR.primaryBg,\n borderRadius: RADIUS.md,\n border: `1px solid ${COLOR.primaryBg}`,\n cursor: 'pointer',\n },\n deepLinkLabel: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.primaryFg,\n },\n deepLinkPath: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n fontFamily: 'monospace',\n },\n systemWrapper: {\n display: 'flex',\n justifyContent: 'center',\n margin: `${SPACE.S2} 0`,\n },\n systemPill: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `5px ${SPACE.S3}`,\n backgroundColor: COLOR.neutral100,\n borderRadius: '999px',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n },\n systemTime: {\n fontSize: '11px',\n color: COLOR.neutral400,\n fontVariantNumeric: 'tabular-nums',\n },\n};\n","import React from 'react';\n\n/**\n * Soft, friendly empty-state illustration for the chat thread.\n * Two overlapping speech bubbles + a subtle background circle. Pure SVG, no\n * external assets so it renders consistently across hosts.\n */\nexport function ChatIllustration({ size = 96 }: { size?: number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 120 120\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"60\" cy=\"60\" r=\"56\" fill=\"#eff6ff\" />\n <path\n 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\"\n fill=\"#ffffff\"\n stroke=\"#2563eb\"\n strokeWidth=\"2.5\"\n />\n <path\n 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\"\n fill=\"#dbeafe\"\n stroke=\"#2563eb\"\n strokeWidth=\"2.5\"\n />\n <circle cx=\"48\" cy=\"53\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"58\" cy=\"53\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"68\" cy=\"68\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"78\" cy=\"68\" r=\"2.5\" fill=\"#2563eb\" />\n </svg>\n );\n}\n","/**\n * Shared date/time labels for the chat UI.\n *\n * Two surfaces consume these:\n * - The inbox row's right-side timestamp ({@link formatInboxTimestamp})\n * - The in-chat day divider pill ({@link formatDayDivider})\n *\n * Bucketing is identical between them, so a conversation labeled \"Tuesday\"\n * in the inbox is grouped under a \"Tuesday\" pill inside its chat β€” no\n * drift between surfaces.\n *\n * Format choices:\n * - Full date: \"15 May 2026\" (fixed English short month, day, year)\n * - Weekday: \"Tuesday\" (fixed English long weekday)\n * - Time: locale-defaulted (respects the user's OS region)\n */\n\nconst SHORT_MONTHS = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\n];\n\nconst LONG_WEEKDAYS = [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',\n];\n\nconst ONE_DAY_MS = 86_400_000;\n\nfunction parseSafe(iso: string): Date | null {\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n/** Returns the start of the day for the given date (local time). */\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Number of calendar days between two dates (local time). Negative if a < b. */\nfunction daysBetween(a: Date, b: Date): number {\n return Math.floor((startOfDay(a).getTime() - startOfDay(b).getTime()) / ONE_DAY_MS);\n}\n\nfunction formatFullDate(d: Date): string {\n return `${d.getDate()} ${SHORT_MONTHS[d.getMonth()]} ${d.getFullYear()}`;\n}\n\nfunction formatLocaleTime(d: Date): string {\n // Locale-default time. Tries to match the user's OS preference for 12h vs\n // 24h. Falls back to a manual 12h format if Intl is unavailable.\n try {\n return d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n } catch {\n const h = d.getHours();\n const m = d.getMinutes().toString().padStart(2, '0');\n const suffix = h >= 12 ? 'PM' : 'AM';\n const h12 = ((h + 11) % 12) + 1;\n return `${h12}:${m} ${suffix}`;\n }\n}\n\n/**\n * Inbox row timestamp (right-edge of each conversation row).\n *\n * today β†’ \"9:42 PM\"\n * yesterday β†’ \"Yesterday\"\n * last 7 days β†’ weekday name (\"Tuesday\")\n * older β†’ \"15 May 2026\"\n */\nexport function formatInboxTimestamp(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n\n const diffDays = daysBetween(new Date(), d);\n\n if (diffDays === 0) return formatLocaleTime(d);\n if (diffDays === 1) return 'Yesterday';\n if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];\n return formatFullDate(d);\n}\n\n/**\n * In-chat day divider pill text.\n *\n * today β†’ \"Today\"\n * yesterday β†’ \"Yesterday\"\n * last 7 days β†’ weekday name (\"Tuesday\")\n * older β†’ \"15 May 2026\"\n */\nexport function formatDayDivider(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n\n const diffDays = daysBetween(new Date(), d);\n\n if (diffDays === 0) return 'Today';\n if (diffDays === 1) return 'Yesterday';\n if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];\n return formatFullDate(d);\n}\n\n/**\n * Stable day-bucket key for grouping messages. Two messages with the same\n * key belong under the same day divider.\n */\nexport function dayBucketKey(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;\n}\n","import React, { useEffect, useLayoutEffect, useRef, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport { MessageBubble } from './MessageBubble';\nimport { Spinner } from './Spinner';\nimport { ChatIllustration } from './icons/ChatIllustration';\nimport { dayBucketKey, formatDayDivider } from '../core/dateLabels';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SHADOW,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Message, Participant, TypingEvent } from '../core/types';\n\nexport interface MessageListHandle {\n /** Scroll to a specific message by ID (used by pin jump-to) */\n scrollToMessage: (messageId: string) => void;\n}\n\ninterface MessageListProps {\n messages: Message[];\n currentUserId: string;\n participants?: Participant[];\n showSeenBy?: boolean;\n typingUsers: TypingEvent[];\n hasMore: boolean;\n isLoading: boolean;\n onLoadMore: () => void;\n onDeepLinkClick?: (link: string) => void;\n onMessageVisible?: (messageId: string) => void;\n onReply?: (message: Message) => void;\n onPin?: (messageId: string) => void;\n onUnpin?: (messageId: string) => void;\n onCopy?: (text: string) => void;\n /** Retry a failed message (own bubbles only) */\n onRetry?: (messageId: string) => void;\n pinDisabled?: boolean;\n className?: string;\n}\n\nexport const MessageList = forwardRef<MessageListHandle, MessageListProps>(function MessageList(\n {\n messages,\n currentUserId,\n participants = [],\n showSeenBy = true,\n typingUsers,\n hasMore,\n isLoading,\n onLoadMore,\n onDeepLinkClick,\n onMessageVisible,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n onRetry,\n pinDisabled,\n className,\n },\n ref\n) {\n const containerRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const prevMessageCount = useRef(messages.length);\n // Tracks whether we've performed the one-time jump-to-bottom on\n // initial load. Without this the auto-scroll effect only fires if the\n // user is \"already near bottom\" β€” which is never true at mount time,\n // so opening a chat would land on the oldest message instead of the\n // latest. CollabPanel keys the panel by orderId so this ref naturally\n // resets when the user switches conversations.\n const hasInitiallyScrolledRef = useRef(false);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToMessage: (messageId: string) => {\n const element = containerRef.current?.querySelector(`[data-message-id=\"${messageId}\"]`);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n // Brief flash to draw attention\n (element as HTMLElement).style.transition = 'background-color 200ms';\n (element as HTMLElement).style.backgroundColor = '#fef3c7';\n setTimeout(() => {\n (element as HTMLElement).style.backgroundColor = '';\n }, 800);\n }\n },\n }),\n []\n );\n\n // Initial positioning β€” runs once per mount, before paint.\n // - If any message is unread by the current user (their userId not\n // in readBy, and they didn't send it) β†’ scroll the FIRST such\n // message to the top of the visible area so the user resumes\n // where they left off.\n // - Otherwise β†’ jump to the bottom so the user sees the latest\n // exchange in a fully-read thread.\n //\n // useLayoutEffect (not useEffect) so the scroll happens before paint\n // β€” no flash of \"scrolled to top\" in between. Direct scrollTop\n // assignment instead of scrollIntoView because the popup has\n // overflow:hidden ancestors that confuse scrollIntoView's choice of\n // scrollable parent.\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container || messages.length === 0) return;\n if (hasInitiallyScrolledRef.current) return;\n\n hasInitiallyScrolledRef.current = true;\n prevMessageCount.current = messages.length;\n\n const firstUnread = messages.find(\n (m) =>\n m.type !== 'system' &&\n m.senderId !== currentUserId &&\n !(m.readBy ?? []).includes(currentUserId)\n );\n\n if (firstUnread) {\n const el = container.querySelector(\n `[data-message-id=\"${firstUnread.id}\"]`\n ) as HTMLElement | null;\n if (el) {\n // Compute the element's offset within the scrollable container\n // via getBoundingClientRect so we don't depend on offsetParent\n // chains. Pad 16px so the day divider above the message stays\n // visible.\n const containerRect = container.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const offset = elRect.top - containerRect.top + container.scrollTop;\n container.scrollTop = Math.max(0, offset - 16);\n return;\n }\n }\n\n container.scrollTop = container.scrollHeight;\n }, [messages, currentUserId]);\n\n // Subsequent message arrivals: smooth-scroll only when it's the\n // user's own send, or they were already near the bottom. Don't yank\n // them away from older messages they're reading.\n useEffect(() => {\n if (!hasInitiallyScrolledRef.current) return;\n if (messages.length > prevMessageCount.current) {\n const lastMessage = messages[messages.length - 1];\n const isOwnMessage = lastMessage?.senderId === currentUserId;\n if (isOwnMessage || isNearBottom(containerRef.current)) {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }\n }\n prevMessageCount.current = messages.length;\n }, [messages, currentUserId]);\n\n // Intersection observer for marking messages as read\n useEffect(() => {\n if (!onMessageVisible || !containerRef.current) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const messageId = (entry.target as HTMLElement).dataset.messageId;\n if (messageId) onMessageVisible(messageId);\n }\n });\n },\n { root: containerRef.current, threshold: 0.5 }\n );\n\n const messageElements = containerRef.current.querySelectorAll('[data-message-id]');\n messageElements.forEach((el) => observer.observe(el));\n\n return () => observer.disconnect();\n }, [messages, onMessageVisible]);\n\n // Scroll-to-top detection for loading more messages\n const handleScroll = useCallback(() => {\n if (!containerRef.current || !hasMore || isLoading) return;\n\n if (containerRef.current.scrollTop < 50) {\n onLoadMore();\n }\n }, [hasMore, isLoading, onLoadMore]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={styles.container}\n onScroll={handleScroll}\n >\n {/* Load more indicator */}\n {isLoading && messages.length > 0 && (\n <div style={styles.loadingMore}>\n <Spinner size={14} />\n <span>Loading earlier messages…</span>\n </div>\n )}\n\n {hasMore && !isLoading && messages.length > 0 && (\n <button onClick={onLoadMore} style={styles.loadMoreButton} type=\"button\">\n Load earlier messages\n </button>\n )}\n\n {/* Empty state */}\n {messages.length === 0 && !isLoading && (\n <div style={styles.empty}>\n <ChatIllustration size={104} />\n <p style={styles.emptyTitle}>No messages yet</p>\n <p style={styles.emptySubtitle}>\n Start the conversation β€” everyone on this case will see what you write.\n </p>\n </div>\n )}\n\n {/* First-load spinner (no messages, still loading) */}\n {messages.length === 0 && isLoading && (\n <div style={styles.firstLoad}>\n <Spinner size={20} />\n </div>\n )}\n\n {/* Message list β€” day dividers inserted when the bucket key changes.\n Messages arrive sorted oldest β†’ newest. We carry the last *valid*\n bucket forward so a single bad insertedAt (yielding \"\") doesn't\n break the divider chain for surrounding messages. */}\n {(() => {\n let lastValidBucket: string | null = null;\n return messages.map((message) => {\n const currentBucket = dayBucketKey(message.insertedAt);\n const showDivider = !!currentBucket && currentBucket !== lastValidBucket;\n if (currentBucket) lastValidBucket = currentBucket;\n\n return (\n <React.Fragment key={message.id}>\n {showDivider && (\n <div style={styles.dayDivider} role=\"separator\" aria-label=\"Date\">\n <span style={styles.dayHr} aria-hidden=\"true\" />\n <span style={styles.dayLabel}>{formatDayDivider(message.insertedAt)}</span>\n <span style={styles.dayHr} aria-hidden=\"true\" />\n </div>\n )}\n <div data-message-id={message.id} data-natoe-message-bubble style={styles.bubbleSlot}>\n <MessageBubble\n message={message}\n isOwn={message.senderId === currentUserId}\n participants={participants}\n currentUserId={currentUserId}\n showSeenBy={showSeenBy}\n onDeepLinkClick={onDeepLinkClick}\n onReply={onReply}\n onPin={onPin}\n onUnpin={onUnpin}\n onCopy={onCopy}\n onRetry={onRetry}\n pinDisabled={pinDisabled}\n />\n </div>\n </React.Fragment>\n );\n });\n })()}\n\n {/* Typing indicators */}\n {typingUsers.length > 0 && (\n <div style={styles.typingIndicator}>\n {typingUsers.map((t) => t.userName ?? 'Someone').join(', ')}\n {typingUsers.length === 1 ? ' is ' : ' are '}typing...\n </div>\n )}\n\n <div ref={bottomRef} />\n </div>\n );\n});\n\nfunction isNearBottom(container: HTMLDivElement | null): boolean {\n if (!container) return true;\n const threshold = 150;\n return container.scrollHeight - container.scrollTop - container.clientHeight < threshold;\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n flex: 1,\n overflowY: 'auto',\n paddingTop: SPACE.S3,\n paddingBottom: SPACE.S2,\n },\n loadingMore: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE.S2,\n padding: SPACE.S3,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n firstLoad: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S4}`,\n },\n loadMoreButton: {\n display: 'block',\n margin: `0 auto ${SPACE.S3}`,\n minHeight: '36px',\n padding: `${SPACE.S2} ${SPACE.S5}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral700,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.pill,\n cursor: 'pointer',\n },\n empty: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S4}`,\n color: COLOR.neutral500,\n },\n emptyTitle: {\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n margin: `${SPACE.S3} 0 ${SPACE.S1}`,\n },\n emptySubtitle: {\n fontSize: FONT_SIZE.sm,\n margin: 0,\n maxWidth: '280px',\n lineHeight: LINE_HEIGHT.normal,\n textAlign: 'center' as const,\n },\n typingIndicator: {\n padding: `${SPACE.S1} ${SPACE.S4} ${SPACE.S2}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n fontStyle: 'italic',\n },\n dayDivider: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n margin: `${SPACE.S4} 0 ${SPACE.S3}`,\n position: 'sticky',\n top: SPACE.S1,\n zIndex: Z_INDEX.sticky,\n pointerEvents: 'none',\n },\n dayHr: {\n flex: 1,\n height: '1px',\n backgroundColor: COLOR.neutral200,\n },\n dayLabel: {\n flexShrink: 0,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n // Subtle pill background so the label is readable when it overlays\n // bubbles passing under it during sticky scroll. Without this the\n // hairlines visually run through the text on tinted backgrounds.\n padding: `2px ${SPACE.S2}`,\n backgroundColor: COLOR.white,\n borderRadius: RADIUS.sm,\n },\n bubbleSlot: {\n animation: 'natoe-colab-message-in 180ms ease-out',\n },\n};\n","import React from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface ReplyPreviewProps {\n /** The message being replied to */\n message: Message;\n /** Called when user cancels the reply */\n onCancel: () => void;\n className?: string;\n}\n\n/**\n * Shown above the MessageInput when the user is composing a reply.\n * Displays the quoted message with a cancel button.\n */\nexport function ReplyPreview({ message, onCancel, className }: ReplyPreviewProps) {\n const preview = renderQuotedPreview(message);\n\n return (\n <div className={className} style={styles.container}>\n <div style={styles.bar} />\n <div style={styles.content}>\n <div style={styles.senderLine}>\n <span style={styles.senderIcon}>↩</span>\n <span style={styles.senderName}>Replying to {message.senderName}</span>\n </div>\n <div style={styles.preview}>{preview}</div>\n </div>\n <button onClick={onCancel} style={styles.cancelButton} title=\"Cancel reply\" type=\"button\">\n βœ•\n </button>\n </div>\n );\n}\n\nfunction renderQuotedPreview(message: Message): string {\n switch (message.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default: {\n const body = message.body || '';\n return body.length > 120 ? `${body.slice(0, 120)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'stretch',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S3}`,\n backgroundColor: COLOR.neutral50,\n borderTop: `1px solid ${COLOR.neutral200}`,\n },\n bar: {\n width: '3px',\n backgroundColor: COLOR.primary,\n borderRadius: '2px',\n flexShrink: 0,\n },\n content: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n minWidth: 0,\n },\n senderLine: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n },\n senderIcon: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n },\n senderName: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n },\n preview: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n cancelButton: {\n alignSelf: 'center',\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n flexShrink: 0,\n },\n};\n","import React from 'react';\n\nexport function AttachIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function SendIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function CloseIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React, { useState, useRef, useCallback, useEffect } from 'react';\n// MIC DISABLED β€” voice messaging temporarily removed. Imports kept for easy re-enable.\n// import { useAudioRecorder } from '../hooks/useAudioRecorder';\n// import { MicIcon } from './icons/MicIcon';\nimport { ReplyPreview } from './ReplyPreview';\nimport { AttachIcon } from './icons/AttachIcon';\nimport { SendIcon } from './icons/SendIcon';\nimport { CloseIcon } from './icons/CloseIcon';\nimport { MAX_FILE_SIZE, SUPPORTED_IMAGE_TYPES } from '../core/constants';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SIZE,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface MessageInputProps {\n onSendText: (body: string) => Promise<void>;\n /** @deprecated MIC DISABLED β€” kept in the prop signature for backward compat. */\n onSendAudio?: (blob: Blob, duration: number) => Promise<void>;\n onSendFile: (file: File) => Promise<void>;\n onTyping: (isTyping: boolean) => void;\n /** When set, shows a ReplyPreview above the input */\n replyTo?: Message | null;\n /** Called when user cancels the reply */\n onCancelReply?: () => void;\n disabled?: boolean;\n placeholder?: string;\n className?: string;\n}\n\nexport function MessageInput({\n onSendText,\n // MIC DISABLED β€” onSendAudio still accepted but unused.\n // onSendAudio,\n onSendFile,\n onTyping,\n replyTo,\n onCancelReply,\n disabled = false,\n placeholder = 'Type a message...',\n className,\n}: MessageInputProps) {\n const [text, setText] = useState('');\n const [isSending, setIsSending] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [fileError, setFileError] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isTypingRef = useRef(false);\n // Synchronous guard β€” useState's async update can't block a second click\n // that lands before React re-renders. The ref flips immediately.\n const sendingRef = useRef(false);\n\n // MIC DISABLED β€” voice recorder hook is not invoked. Restore by uncommenting\n // the original destructure below (and the import at the top of the file).\n // const { isRecording, duration, start: startRecording, stop: stopRecording, cancel: cancelRecording, isSupported: micSupported, error: micError } = useAudioRecorder();\n\n // Rising-edge only β€” fire once when the user starts typing, then a single\n // \"stopped\" event after 2s of idle. Previously this called onTyping(true)\n // on EVERY keystroke, flooding the socket with redundant events.\n const handleTyping = useCallback(() => {\n if (!isTypingRef.current) {\n isTypingRef.current = true;\n onTyping(true);\n }\n\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n typingTimeoutRef.current = setTimeout(() => {\n isTypingRef.current = false;\n onTyping(false);\n }, 2000);\n }, [onTyping]);\n\n useEffect(() => {\n return () => {\n if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);\n };\n }, []);\n\n const handleSendText = useCallback(async () => {\n const trimmed = text.trim();\n if (!trimmed || sendingRef.current) return;\n\n sendingRef.current = true;\n setIsSending(true);\n if (isTypingRef.current) {\n isTypingRef.current = false;\n onTyping(false);\n }\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n typingTimeoutRef.current = null;\n }\n\n try {\n await onSendText(trimmed);\n setText('');\n } finally {\n sendingRef.current = false;\n setIsSending(false);\n }\n }, [text, onSendText, onTyping]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSendText();\n }\n },\n [handleSendText]\n );\n\n // MIC DISABLED β€” audio stop handler unused. Restore alongside useAudioRecorder.\n // const handleAudioStop = useCallback(async () => {\n // const result = await stopRecording();\n // if (result) {\n // setIsSending(true);\n // try {\n // await onSendAudio(result.blob, result.duration);\n // } finally {\n // setIsSending(false);\n // }\n // }\n // }, [stopRecording, onSendAudio]);\n\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n setFileError(null);\n\n if (file.size > MAX_FILE_SIZE) {\n setFileError(`File too large. Maximum size is ${MAX_FILE_SIZE / (1024 * 1024)}MB.`);\n return;\n }\n\n setIsSending(true);\n setIsUploading(true);\n try {\n await onSendFile(file);\n } finally {\n setIsSending(false);\n setIsUploading(false);\n // Reset file input\n if (fileInputRef.current) fileInputRef.current.value = '';\n }\n },\n [onSendFile]\n );\n\n return (\n <div className={className} style={styles.container}>\n {/* Reply preview */}\n {replyTo && onCancelReply && (\n <ReplyPreview message={replyTo} onCancel={onCancelReply} />\n )}\n\n {/* Upload progress banner */}\n {isUploading && (\n <div style={styles.uploadBanner}>\n <span style={styles.uploadSpinner} />\n Uploading file…\n </div>\n )}\n\n {/* Error messages */}\n {fileError && (\n <div style={styles.error} role=\"alert\">\n <span style={styles.errorText}>{fileError}</span>\n <button\n type=\"button\"\n onClick={() => setFileError(null)}\n aria-label=\"Dismiss error\"\n style={styles.errorDismiss}\n >\n <CloseIcon size={16} />\n </button>\n </div>\n )}\n\n {/* MIC DISABLED β€” recording bar and mic button removed.\n Original blocks kept here for easy re-enable:\n\n {isRecording ? (\n <div style={styles.recordingBar}>\n <div style={styles.recordingIndicator}>\n <span style={styles.recordingDot} />\n Recording {formatDuration(duration)}\n </div>\n <div style={styles.recordingActions}>\n <button onClick={cancelRecording} style={styles.cancelButton} type=\"button\">Cancel</button>\n <button onClick={handleAudioStop} style={styles.stopButton} type=\"button\">Send</button>\n </div>\n </div>\n ) : (\n ...input bar with mic button...\n )}\n */}\n <div style={styles.inputBar}>\n {/* MIC DISABLED β€” mic button hidden.\n {micSupported && (\n <button onClick={startRecording} disabled={disabled || isSending} style={styles.iconButton} title=\"Record voice message\" type=\"button\">\n <MicIcon size={20} color=\"#374151\" />\n </button>\n )}\n */}\n\n {/* File attach β€” 48px square tile, prototype-style */}\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={disabled || isSending}\n style={styles.attachButton}\n aria-label=\"Attach file\"\n title=\"Attach file\"\n type=\"button\"\n >\n <AttachIcon size={22} color={COLOR.neutral700} />\n </button>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n accept={[\n ...SUPPORTED_IMAGE_TYPES,\n 'application/pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.csv',\n '.txt',\n '.heic',\n '.heif',\n ].join(',')}\n />\n\n {/* Text input */}\n <textarea\n value={text}\n onChange={(e) => {\n setText(e.target.value);\n handleTyping();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || isSending}\n rows={1}\n style={styles.textarea}\n />\n\n {/* Send β€” icon + \"Send\" label, prototype-style pill */}\n <button\n onClick={handleSendText}\n disabled={disabled || isSending || !text.trim()}\n aria-label=\"Send message\"\n title=\"Send message\"\n style={{\n ...styles.sendButton,\n opacity: text.trim() ? 1 : 0.5,\n }}\n type=\"button\"\n >\n <SendIcon size={20} color={COLOR.white} />\n <span style={styles.sendLabel}>Send</span>\n </button>\n </div>\n </div>\n );\n}\n\n// MIC DISABLED β€” formatDuration was only used by the recording UI.\n// Kept here for easy restore when mic is re-enabled.\n// function formatDuration(seconds: number): string {\n// const m = Math.floor(seconds / 60);\n// const s = seconds % 60;\n// return `${m}:${s.toString().padStart(2, '0')}`;\n// }\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n borderTop: `1px solid ${COLOR.neutral200}`,\n backgroundColor: COLOR.white,\n },\n uploadBanner: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: COLOR.neutral50,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n uploadSpinner: {\n display: 'inline-block',\n width: '12px',\n height: '12px',\n border: `2px solid ${COLOR.neutral300}`,\n borderTopColor: COLOR.primary,\n borderRadius: RADIUS.full,\n animation: 'natoe-colab-spin 0.7s linear infinite',\n flexShrink: 0,\n },\n error: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S3} ${SPACE.S2} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.dangerFg,\n backgroundColor: COLOR.dangerBg,\n borderTop: `1px solid ${COLOR.dangerBorder}`,\n },\n errorText: {\n flex: 1,\n minWidth: 0,\n },\n errorDismiss: {\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n color: COLOR.dangerFg,\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n flexShrink: 0,\n },\n inputBar: {\n display: 'flex',\n alignItems: 'flex-end',\n gap: '10px',\n padding: `${SPACE.S3} ${SPACE.S4} 14px`,\n },\n // 48px square tile with a 14px corner radius β€” visually grounds the\n // attach affordance as part of the composer chrome rather than a stray\n // round icon button.\n attachButton: {\n width: '48px',\n height: '48px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n color: COLOR.neutral700,\n transition: 'background-color 120ms ease, color 120ms ease, border-color 120ms ease',\n },\n iconButton: {\n width: SIZE.controlPrimary,\n height: SIZE.controlPrimary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n textarea: {\n flex: 1,\n minHeight: '48px',\n maxHeight: '140px',\n padding: '13px 16px',\n fontSize: FONT_SIZE.md,\n lineHeight: LINE_HEIGHT.normal,\n color: COLOR.neutral900,\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n resize: 'none',\n outline: 'none',\n fontFamily: 'inherit',\n transition: 'background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease',\n },\n // Pill-shaped send: icon + \"Send\" label. Always labelled (never icon-\n // only) so the affordance is obvious to first-time users.\n sendButton: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '6px',\n minWidth: '48px',\n height: '48px',\n padding: `0 ${SPACE.S4}`,\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n border: 'none',\n borderRadius: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n fontFamily: 'inherit',\n fontSize: '15px',\n fontWeight: FONT_WEIGHT.semibold,\n transition: 'opacity 120ms ease, background-color 120ms ease',\n },\n sendLabel: {\n lineHeight: 1,\n },\n recordingBar: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: `${SPACE.S3} ${SPACE.S4}`,\n backgroundColor: COLOR.dangerBg,\n },\n recordingIndicator: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n fontWeight: FONT_WEIGHT.medium,\n },\n recordingDot: {\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.danger,\n animation: 'pulse 1.5s infinite',\n },\n recordingActions: {\n display: 'flex',\n gap: SPACE.S2,\n },\n cancelButton: {\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n stopButton: {\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n};\n","import React from 'react';\nimport { COLOR, FONT_SIZE, FONT_WEIGHT, RADIUS, SPACE } from '../core/theme';\nimport type { Participant, UserRole } from '../core/types';\n\ninterface ParticipantsListProps {\n participants: Participant[];\n currentUserId: string;\n isAdmin: boolean;\n onRemoveUser: (userId: string) => Promise<void>;\n className?: string;\n}\n\nexport function ParticipantsList({\n participants,\n currentUserId,\n isAdmin,\n onRemoveUser,\n className,\n}: ParticipantsListProps) {\n return (\n <div className={className} style={styles.list}>\n {participants.map((participant) => (\n <div key={participant.userId} style={styles.item}>\n {/* Avatar */}\n <div style={styles.avatar}>\n {participant.avatar ? (\n <img src={participant.avatar} alt=\"\" style={styles.avatarImg} />\n ) : (\n <span style={styles.avatarFallback}>\n {(participant.userName ?? '?').charAt(0).toUpperCase()}\n </span>\n )}\n {/* Online indicator */}\n <span\n style={{\n ...styles.statusDot,\n backgroundColor: participant.isOnline ? COLOR.success : COLOR.neutral300,\n }}\n />\n </div>\n\n {/* Info */}\n <div style={styles.info}>\n <span style={styles.name}>\n {participant.userName ?? fallbackName(participant.userRole)}\n {participant.userId === currentUserId && (\n <span style={styles.youBadge}> (you)</span>\n )}\n </span>\n <RoleBadge role={participant.userRole} />\n </div>\n\n {/* Remove button (admin only, can't remove self) */}\n {isAdmin && participant.userId !== currentUserId && (\n <button\n onClick={() => onRemoveUser(participant.userId)}\n style={styles.removeButton}\n title={`Remove ${participant.userName ?? fallbackName(participant.userRole)}`}\n type=\"button\"\n >\n βœ•\n </button>\n )}\n </div>\n ))}\n </div>\n );\n}\n\nfunction fallbackName(role: UserRole): string {\n switch (role) {\n case 'lab':\n return 'Imaging Center';\n case 'radiologist':\n return 'Radiologist';\n case 'physician':\n return 'Physician';\n case 'admin':\n return 'Natoe Admin';\n default:\n return 'User';\n }\n}\n\nfunction RoleBadge({ role }: { role: UserRole }) {\n // Cool-only palette β€” matches MessageBubble.roleColor() and CollabInline.\n // No greens / reds / purples; roles stay distinguishable via tone\n // (indigo / brand-blue / sky / slate) within the blue family.\n const colors: Record<UserRole, { bg: string; text: string }> = {\n radiologist: { bg: '#eef2ff', text: '#4f46e5' }, // indigo\n lab: { bg: '#eff6ff', text: '#2563eb' }, // brand blue\n physician: { bg: '#e0f2fe', text: '#0284c7' }, // sky\n admin: { bg: '#f1f5f9', text: '#64748b' }, // slate\n };\n\n const color = colors[role];\n\n return (\n <span style={{ ...styles.roleBadge, backgroundColor: color.bg, color: color.text }}>\n {role}\n </span>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n list: {\n display: 'flex',\n flexDirection: 'column',\n },\n item: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n padding: `${SPACE.S2} 0`,\n borderBottom: `1px solid ${COLOR.neutral50}`,\n },\n avatar: {\n position: 'relative',\n width: '32px',\n height: '32px',\n flexShrink: 0,\n },\n avatarImg: {\n width: '32px',\n height: '32px',\n borderRadius: RADIUS.full,\n objectFit: 'cover' as const,\n },\n avatarFallback: {\n width: '32px',\n height: '32px',\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.neutral200,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n },\n statusDot: {\n position: 'absolute' as const,\n bottom: '0',\n right: '0',\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n border: `2px solid ${COLOR.white}`,\n },\n info: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n flex: 1,\n minWidth: 0,\n },\n name: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n youBadge: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.regular,\n color: COLOR.neutral400,\n },\n roleBadge: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n padding: `2px ${SPACE.S2}`,\n borderRadius: RADIUS.sm,\n whiteSpace: 'nowrap' as const,\n },\n removeButton: {\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral400,\n flexShrink: 0,\n },\n};\n","import React, { useState } from 'react';\nimport { ParticipantsList } from './ParticipantsList';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Participant, InviteUserPayload, UserRole, CollabError } from '../core/types';\n\ninterface ChannelSettingsProps {\n conversationId: string;\n channelName: string;\n channelPicture?: string;\n participants: Participant[];\n currentUserId: string;\n isAdmin: boolean;\n isUpdating: boolean;\n error: CollabError | null;\n onUpdateChannel: (payload: { name?: string; picture?: string }) => Promise<void>;\n onInviteUser: (payload: InviteUserPayload) => Promise<void>;\n onRemoveUser: (userId: string) => Promise<void>;\n onLeaveChannel: () => Promise<void>;\n onDeleteChannel: () => Promise<void>;\n onClose: () => void;\n className?: string;\n}\n\nexport function ChannelSettings({\n channelName,\n participants,\n currentUserId,\n isAdmin,\n isUpdating,\n error,\n onUpdateChannel,\n onInviteUser,\n onRemoveUser,\n onLeaveChannel,\n onDeleteChannel,\n onClose,\n className,\n}: ChannelSettingsProps) {\n const [editingName, setEditingName] = useState(false);\n const [nameValue, setNameValue] = useState(channelName);\n const [showInvite, setShowInvite] = useState(false);\n const [inviteId, setInviteId] = useState('');\n const [inviteName, setInviteName] = useState('');\n const [inviteRole, setInviteRole] = useState<UserRole>('radiologist');\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n const handleSaveName = async () => {\n if (nameValue.trim() && nameValue !== channelName) {\n await onUpdateChannel({ name: nameValue.trim() });\n }\n setEditingName(false);\n };\n\n const handleInvite = async () => {\n if (!inviteId.trim() || !inviteName.trim()) return;\n await onInviteUser({\n userId: inviteId.trim(),\n userName: inviteName.trim(),\n userRole: inviteRole,\n });\n setInviteId('');\n setInviteName('');\n setShowInvite(false);\n };\n\n const handleDelete = async () => {\n if (!confirmDelete) {\n setConfirmDelete(true);\n return;\n }\n await onDeleteChannel();\n };\n\n return (\n <div className={className} style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <h3 style={styles.title}>Channel Settings</h3>\n <button onClick={onClose} style={styles.closeButton} type=\"button\">\n βœ•\n </button>\n </div>\n\n {/* Error */}\n {error && (\n <div style={styles.error}>{error.message}</div>\n )}\n\n {/* Channel name */}\n <div style={styles.section}>\n <label style={styles.label}>Channel Name</label>\n {editingName ? (\n <div style={styles.editRow}>\n <input\n value={nameValue}\n onChange={(e) => setNameValue(e.target.value)}\n style={styles.input}\n autoFocus\n />\n <button onClick={handleSaveName} disabled={isUpdating} style={styles.saveButton} type=\"button\">\n Save\n </button>\n <button onClick={() => setEditingName(false)} style={styles.cancelButton} type=\"button\">\n Cancel\n </button>\n </div>\n ) : (\n <div style={styles.editRow}>\n <span style={styles.channelName}>{channelName}</span>\n <button onClick={() => setEditingName(true)} style={styles.editButton} type=\"button\">\n Edit\n </button>\n </div>\n )}\n </div>\n\n {/* Participants */}\n <div style={styles.section}>\n <div style={styles.sectionHeader}>\n <label style={styles.label}>Participants ({participants.length})</label>\n <button onClick={() => setShowInvite(!showInvite)} style={styles.addButton} type=\"button\">\n + Add\n </button>\n </div>\n\n {/* Invite form */}\n {showInvite && (\n <div style={styles.inviteForm}>\n <input\n value={inviteId}\n onChange={(e) => setInviteId(e.target.value)}\n placeholder=\"User ID\"\n style={styles.input}\n />\n <input\n value={inviteName}\n onChange={(e) => setInviteName(e.target.value)}\n placeholder=\"User Name\"\n style={styles.input}\n />\n <select\n value={inviteRole}\n onChange={(e) => setInviteRole(e.target.value as UserRole)}\n style={styles.input}\n >\n <option value=\"radiologist\">Radiologist</option>\n <option value=\"lab\">Lab</option>\n <option value=\"physician\">Physician</option>\n <option value=\"admin\">Admin</option>\n </select>\n <div style={styles.inviteActions}>\n <button onClick={handleInvite} disabled={isUpdating} style={styles.saveButton} type=\"button\">\n Invite\n </button>\n <button onClick={() => setShowInvite(false)} style={styles.cancelButton} type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n )}\n\n <ParticipantsList\n participants={participants}\n currentUserId={currentUserId}\n isAdmin={isAdmin}\n onRemoveUser={onRemoveUser}\n />\n </div>\n\n {/* Actions */}\n <div style={styles.dangerZone}>\n <button onClick={onLeaveChannel} disabled={isUpdating} style={styles.leaveButton} type=\"button\">\n Leave Channel\n </button>\n\n {isAdmin && (\n <button\n onClick={handleDelete}\n disabled={isUpdating}\n style={confirmDelete ? styles.confirmDeleteButton : styles.deleteButton}\n type=\"button\"\n >\n {confirmDelete ? 'Confirm Delete' : 'Delete Channel'}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n },\n header: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: `${SPACE.S3} ${SPACE.S4}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n title: {\n margin: 0,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n },\n closeButton: {\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n error: {\n padding: `${SPACE.S2} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n },\n section: {\n padding: SPACE.S4,\n borderBottom: `1px solid ${COLOR.neutral100}`,\n },\n sectionHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: SPACE.S2,\n },\n label: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n channelName: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral900,\n },\n editRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n marginTop: SPACE.S2,\n },\n input: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n outline: 'none',\n width: '100%',\n },\n editButton: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n },\n saveButton: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n whiteSpace: 'nowrap' as const,\n },\n cancelButton: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n whiteSpace: 'nowrap' as const,\n },\n addButton: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.primary,\n backgroundColor: COLOR.primaryBg,\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n },\n inviteForm: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: SPACE.S2,\n padding: SPACE.S3,\n marginBottom: SPACE.S3,\n backgroundColor: COLOR.neutral50,\n borderRadius: RADIUS.md,\n },\n inviteActions: {\n display: 'flex',\n gap: SPACE.S2,\n },\n dangerZone: {\n padding: SPACE.S4,\n marginTop: 'auto',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: SPACE.S2,\n },\n leaveButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.warning,\n backgroundColor: '#fffbeb',\n border: '1px solid #fde68a',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n deleteButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n confirmDeleteButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n};\n","import React, { useState } from 'react';\nimport { PinIcon } from './icons/PinIcon';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface PinnedMessagesBarProps {\n pinnedMessages: Message[];\n /** Clicking a pinned message scrolls to it in the thread */\n onJumpTo: (messageId: string) => void;\n /** Called when user unpins a message */\n onUnpin: (messageId: string) => void;\n className?: string;\n}\n\n/**\n * Horizontal strip at the top of the thread showing pinned messages (max 3).\n * Cycles through them on click if more than one.\n */\nexport function PinnedMessagesBar({\n pinnedMessages,\n onJumpTo,\n onUnpin,\n className,\n}: PinnedMessagesBarProps) {\n const [index, setIndex] = useState(0);\n\n if (pinnedMessages.length === 0) return null;\n\n const safeIndex = Math.min(index, pinnedMessages.length - 1);\n const current = pinnedMessages[safeIndex];\n const preview = renderPinPreview(current);\n\n const handleClick = () => {\n onJumpTo(current.id);\n if (pinnedMessages.length > 1) {\n setIndex((prev) => (prev + 1) % pinnedMessages.length);\n }\n };\n\n return (\n <div className={className} style={styles.container}>\n <div style={styles.indicator}>\n <PinIcon size={14} color={COLOR.primary} />\n {pinnedMessages.length > 1 && (\n <div style={styles.segments}>\n {pinnedMessages.map((_, i) => (\n <span\n key={i}\n style={{\n ...styles.segment,\n backgroundColor: i === safeIndex ? COLOR.primary : COLOR.neutral300,\n }}\n />\n ))}\n </div>\n )}\n </div>\n\n <button\n onClick={handleClick}\n style={styles.contentButton}\n type=\"button\"\n title=\"Click to jump to message\"\n >\n <div style={styles.label}>\n Pinned {pinnedMessages.length > 1 ? `(${safeIndex + 1}/${pinnedMessages.length})` : ''}\n </div>\n <div style={styles.preview}>\n <span style={styles.sender}>{current.senderName}:</span> {preview}\n </div>\n </button>\n\n <button\n onClick={(e) => {\n e.stopPropagation();\n onUnpin(current.id);\n }}\n style={styles.unpinButton}\n title=\"Unpin this message\"\n type=\"button\"\n >\n βœ•\n </button>\n </div>\n );\n}\n\nfunction renderPinPreview(message: Message): string {\n switch (message.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default: {\n const body = message.body || '';\n return body.length > 100 ? `${body.slice(0, 100)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S3}`,\n backgroundColor: COLOR.primaryBg,\n borderBottom: `1px solid ${COLOR.primaryBg}`,\n },\n indicator: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n flexShrink: 0,\n },\n segments: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n },\n segment: {\n width: '3px',\n height: '6px',\n borderRadius: '1px',\n },\n contentButton: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: '2px 0',\n backgroundColor: 'transparent',\n border: 'none',\n textAlign: 'left',\n cursor: 'pointer',\n minWidth: 0,\n overflow: 'hidden',\n },\n label: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n },\n preview: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral700,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n sender: {\n fontWeight: FONT_WEIGHT.semibold,\n },\n unpinButton: {\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n flexShrink: 0,\n },\n};\n","import React, { useEffect } from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SHADOW,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\n\nexport interface ToastState {\n message: string;\n actionLabel?: string;\n onAction?: () => void;\n}\n\ninterface ToastProps {\n toast: ToastState | null;\n onDismiss: () => void;\n /** Auto-dismiss duration in ms. Default 4000. */\n durationMs?: number;\n}\n\n/**\n * Brief in-app confirmation (Pinned / Unpinned / Copied, etc.) with an\n * optional action button. Auto-dismisses after `durationMs`. Anchored to\n * the bottom of its containing positioned ancestor.\n */\nexport function Toast({ toast, onDismiss, durationMs = 4000 }: ToastProps) {\n useEffect(() => {\n if (!toast) return;\n const timer = setTimeout(onDismiss, durationMs);\n return () => clearTimeout(timer);\n }, [toast, onDismiss, durationMs]);\n\n if (!toast) return null;\n\n return (\n <div style={styles.container} role=\"status\" aria-live=\"polite\">\n <span style={styles.message}>{toast.message}</span>\n {toast.actionLabel && toast.onAction && (\n <button\n type=\"button\"\n onClick={() => {\n toast.onAction?.();\n onDismiss();\n }}\n style={styles.action}\n >\n {toast.actionLabel}\n </button>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n position: 'absolute',\n bottom: '76px',\n left: '50%',\n transform: 'translateX(-50%)',\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n padding: `${SPACE.S3} ${SPACE.S4}`,\n backgroundColor: COLOR.slate800,\n color: COLOR.white,\n borderRadius: RADIUS.md,\n boxShadow: SHADOW.toast,\n fontSize: FONT_SIZE.sm,\n maxWidth: '90%',\n zIndex: Z_INDEX.toast,\n },\n message: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n action: {\n background: 'transparent',\n border: 'none',\n color: COLOR.primaryBg,\n fontWeight: FONT_WEIGHT.semibold,\n fontSize: FONT_SIZE.sm,\n cursor: 'pointer',\n padding: `${SPACE.S1} ${SPACE.S2}`,\n textTransform: 'uppercase',\n letterSpacing: '0.4px',\n },\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport { useConversation } from '../hooks/useConversation';\nimport { useChannelSettings } from '../hooks/useChannelSettings';\nimport { useDeepLinks } from '../hooks/useDeepLinks';\nimport { useCollab } from '../context/CollabProvider';\nimport { PatientHeader } from './PatientHeader';\nimport { MessageList, type MessageListHandle } from './MessageList';\nimport { MessageInput } from './MessageInput';\nimport { ChannelSettings } from './ChannelSettings';\nimport { PinnedMessagesBar } from './PinnedMessagesBar';\nimport { Toast, type ToastState } from './Toast';\nimport { MAX_PINNED_MESSAGES } from '../core/constants';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Conversation, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\ninterface CollabPanelProps {\n /** Order ID β€” one conversation per study */\n orderId: string;\n /** Patient/study data displayed in the header */\n patientData: PatientData;\n /** Participant user IDs β€” only used when creating a brand-new conversation */\n participantIds?: string[];\n /** Show \"seen by\" indicator under own messages (default true) */\n showSeenBy?: boolean;\n /**\n * When set, the header renders a back-arrow button (used by CollabInbox in\n * its compact / single-pane layout to return to the conversation list).\n */\n onBack?: () => void;\n /** Hide the patient name row in the header β€” set when a parent already shows it (e.g. CollabPopup title bar) */\n hidePatientName?: boolean;\n /**\n * Notified whenever the underlying conversation state changes (initial\n * preview load, create, channel deletion). Lets a parent like CollabPopup\n * render its title bar from the authoritative conversation.name instead of\n * relying on potentially-incomplete patientData.\n */\n onConversationChange?: (conversation: Conversation | null) => void;\n /** Custom class name for the outer container */\n className?: string;\n /** Custom inline styles for the outer container */\n style?: React.CSSProperties;\n}\n\n/**\n * Full collaboration panel: patient header + pinned bar + message thread + input.\n * Supports reply, pin/unpin, and (optionally) seen-by indicators.\n */\nexport function CollabPanel({\n orderId,\n patientData,\n participantIds,\n showSeenBy = true,\n onBack,\n hidePatientName = false,\n onConversationChange,\n className,\n style,\n}: CollabPanelProps) {\n const { config } = useCollab();\n const [showSettings, setShowSettings] = useState(false);\n const [toast, setToast] = useState<ToastState | null>(null);\n const messageListRef = useRef<MessageListHandle>(null);\n\n const {\n conversation,\n messages,\n pinnedMessages,\n participants,\n typingUsers,\n isLoading,\n hasMore,\n error,\n replyTo,\n setReplyTo,\n sendMessage,\n retryMessage,\n sendAudioMessage,\n sendFileMessage,\n sendTyping,\n markAsRead,\n loadMoreMessages,\n pinMessage,\n unpinMessage,\n } = useConversation({ orderId, patientData, participantIds });\n\n // Surface conversation state to parents (CollabPopup uses this to render\n // its title bar from the authoritative conversation.name, which is\n // correct even when the host's patientData.labName is missing).\n useEffect(() => {\n onConversationChange?.(conversation);\n }, [conversation, onConversationChange]);\n\n const channelSettings = useChannelSettings({\n conversationId: conversation?.id ?? null,\n });\n\n const { handleDeepLink } = useDeepLinks();\n\n const handleOpenDicom = () => {\n if (patientData.studyId && patientData.storageId && config.onOpenDicom) {\n config.onOpenDicom(patientData.studyId, patientData.storageId);\n }\n };\n\n const handleJumpToMessage = (messageId: string) => {\n messageListRef.current?.scrollToMessage(messageId);\n };\n\n const handleCopy = async (text: string) => {\n try {\n if (navigator.clipboard) {\n await navigator.clipboard.writeText(text);\n setToast({ message: 'Copied to clipboard' });\n }\n } catch {\n // Silent fail β€” clipboard not available\n }\n };\n\n const handlePin = async (messageId: string) => {\n try {\n await pinMessage(messageId);\n setToast({\n message: 'Pinned',\n actionLabel: 'Undo',\n onAction: () => {\n void unpinMessage(messageId);\n },\n });\n } catch {\n setToast({ message: 'Could not pin message' });\n }\n };\n\n const handleUnpin = async (messageId: string) => {\n try {\n await unpinMessage(messageId);\n setToast({ message: 'Unpinned' });\n } catch {\n setToast({ message: 'Could not unpin message' });\n }\n };\n\n const pinDisabled = pinnedMessages.length >= MAX_PINNED_MESSAGES;\n\n if (error) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={{ ...panelStyles.container, ...style }}>\n <div style={panelStyles.errorState}>\n <p style={panelStyles.errorTitle}>Unable to load conversation</p>\n <p style={panelStyles.errorMessage}>{error}</p>\n </div>\n </div>\n );\n }\n\n if (isLoading && !conversation) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={{ ...panelStyles.container, ...style }}>\n <div style={panelStyles.loadingState}>Loading conversation...</div>\n </div>\n );\n }\n\n return (\n <div className={className} style={{ ...panelStyles.container, ...style }}>\n {showSettings && conversation ? (\n <ChannelSettings\n conversationId={conversation.id}\n channelName={conversation.name}\n channelPicture={conversation.picture}\n participants={participants}\n currentUserId={config.userId}\n isAdmin={channelSettings.isAdmin}\n isUpdating={channelSettings.isUpdating}\n error={channelSettings.error}\n onUpdateChannel={channelSettings.updateChannel}\n onInviteUser={channelSettings.inviteUser}\n onRemoveUser={channelSettings.removeUser}\n onLeaveChannel={channelSettings.leaveChannel}\n onDeleteChannel={channelSettings.deleteChannel}\n onClose={() => setShowSettings(false)}\n />\n ) : (\n <>\n <PatientHeader\n patientData={patientData}\n participants={participants}\n onOpenDicom={handleOpenDicom}\n onOpenSettings={() => setShowSettings(true)}\n onBack={onBack}\n hideName={hidePatientName}\n displayName={conversation?.name}\n />\n\n {pinnedMessages.length > 0 && (\n <PinnedMessagesBar\n pinnedMessages={pinnedMessages}\n onJumpTo={handleJumpToMessage}\n onUnpin={handleUnpin}\n />\n )}\n\n <MessageList\n ref={messageListRef}\n messages={messages}\n currentUserId={config.userId}\n participants={participants}\n showSeenBy={showSeenBy}\n typingUsers={typingUsers}\n hasMore={hasMore}\n isLoading={isLoading}\n onLoadMore={loadMoreMessages}\n onDeepLinkClick={handleDeepLink}\n onMessageVisible={markAsRead}\n onReply={setReplyTo}\n onPin={handlePin}\n onUnpin={handleUnpin}\n onCopy={handleCopy}\n onRetry={retryMessage}\n pinDisabled={pinDisabled}\n />\n\n <MessageInput\n onSendText={sendMessage}\n onSendAudio={sendAudioMessage}\n onSendFile={sendFileMessage}\n onTyping={sendTyping}\n replyTo={replyTo}\n onCancelReply={() => setReplyTo(null)}\n />\n </>\n )}\n <Toast toast={toast} onDismiss={() => setToast(null)} />\n </div>\n );\n}\n\nconst panelStyles: Record<string, React.CSSProperties> = {\n container: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n borderRadius: RADIUS.md,\n overflow: 'hidden',\n border: `1px solid ${COLOR.neutral200}`,\n fontFamily: FONT_STACK,\n },\n loadingState: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n errorState: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n padding: SPACE.S6,\n textAlign: 'center',\n },\n errorTitle: {\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n margin: `0 0 ${SPACE.S1}`,\n },\n errorMessage: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n margin: 0,\n },\n};\n","import React from 'react';\n\nexport function MinimizeIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M6 19h12v2H6z\" />\n </svg>\n );\n}\n\nexport function ExpandIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M4 4h16v16H4V4zm2 4v10h12V8H6z\" />\n </svg>\n );\n}\n","import React, { useState, useRef, useCallback, useEffect, useId } from 'react';\nimport { CollabPanel } from './CollabPanel';\nimport { buildChannelName, cleanChannelName } from '../core/channelName';\nimport { CloseIcon } from './icons/CloseIcon';\nimport { MinimizeIcon, ExpandIcon } from './icons/MinimizeIcon';\nimport { BackIcon } from './icons/BackIcon';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Conversation, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\n// Selector covering everything the focus trap considers focusable. Excludes\n// disabled controls and elements opted out via tabindex=\"-1\".\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\ninterface CollabPopupProps {\n /** Order ID for this conversation */\n orderId: string;\n /** Patient/study data */\n patientData: PatientData;\n /** Participant user IDs β€” only used when creating a brand-new conversation */\n participantIds?: string[];\n /** Whether the popup is open */\n isOpen: boolean;\n /** Close the popup */\n onClose: () => void;\n /** Optional back navigation β€” renders a ← button in the title bar when provided */\n onBack?: () => void;\n /**\n * When provided, the minimize button calls this callback instead of\n * toggling the popup's own shrink-to-titlebar state. Hosts use this\n * to minimize the popup to an external chip / dock. With this set the\n * minimize button always shows the minimize glyph (no expand state),\n * since the host owns the open/minimized lifecycle.\n */\n onMinimize?: () => void;\n /** Initial position (defaults to bottom-right) */\n initialPosition?: { x: number; y: number };\n /** Width of the popup */\n width?: number;\n /** Height of the popup */\n height?: number;\n className?: string;\n}\n\n/**\n * Draggable floating chat popup β€” drop-in replacement for DraggableChatPopup.\n * Renders a CollabPanel inside a movable, resizable container.\n */\nexport function CollabPopup({\n orderId,\n patientData,\n participantIds,\n isOpen,\n onClose,\n onBack,\n onMinimize,\n initialPosition,\n width = 380,\n height = 520,\n className,\n}: CollabPopupProps) {\n // Default spawn: anchored bottom-right but offset vertically by enough\n // to clear a standard FAB (56px) + its 24px margin + visual breathing room\n // so the popup never lands on top of a host-app launcher button.\n const [position, setPosition] = useState(\n initialPosition || {\n x: window.innerWidth - width - 24,\n y: Math.max(24, window.innerHeight - height - 104),\n }\n );\n const [isDragging, setIsDragging] = useState(false);\n const [isMinimized, setIsMinimized] = useState(false);\n // Loaded conversation surfaced by CollabPanel's onConversationChange.\n // Used to render the title bar from the authoritative conversation.name\n // instead of relying on the host's patientData (which may be missing\n // labName when reopened from a stored snapshot that lacks it).\n const [loadedConversation, setLoadedConversation] = useState<Conversation | null>(null);\n const dragOffset = useRef({ x: 0, y: 0 });\n const containerRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Prefer the server-stored conversation.name (sanitized) once loaded;\n // fall back to the local builder against patientData while we're still\n // waiting for the preview.\n const titleText =\n cleanChannelName(loadedConversation?.name) || buildChannelName(patientData);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n // Only allow dragging from the drag handle area\n if (!(e.target as HTMLElement).closest('[data-drag-handle]')) return;\n\n setIsDragging(true);\n dragOffset.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n };\n e.preventDefault();\n },\n [position]\n );\n\n // ESC closes; Tab is constrained inside the popup so keyboard users can't\n // accidentally leave the dialog into the page behind. On open we move focus\n // into the popup; on close we put it back where it came from.\n useEffect(() => {\n if (!isOpen) return;\n\n previouslyFocused.current = document.activeElement as HTMLElement | null;\n\n // Defer one frame so the dialog contents have mounted before we look for\n // focusables (CollabPanel renders async branches).\n const focusFirst = () => {\n const root = containerRef.current;\n if (!root) return;\n const first = root.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n (first ?? root).focus();\n };\n const raf = requestAnimationFrame(focusFirst);\n\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose();\n return;\n }\n if (e.key !== 'Tab') return;\n\n const root = containerRef.current;\n if (!root) return;\n const focusables = Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));\n if (focusables.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n window.addEventListener('keydown', handleKey);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener('keydown', handleKey);\n previouslyFocused.current?.focus?.();\n };\n }, [isOpen, onClose]);\n\n useEffect(() => {\n if (!isDragging) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n setPosition({\n x: Math.max(0, Math.min(e.clientX - dragOffset.current.x, window.innerWidth - width)),\n y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ? 52 : height))),\n });\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, width, height, isMinimized]);\n\n if (!isOpen) return null;\n\n return (\n <div\n ref={containerRef}\n className={[ROOT_CLASS, className].filter(Boolean).join(' ')}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n tabIndex={-1}\n style={{\n ...styles.container,\n left: position.x,\n top: position.y,\n width,\n height: isMinimized ? 52 : height,\n cursor: isDragging ? 'grabbing' : 'default',\n }}\n onMouseDown={handleMouseDown}\n >\n {/* Window header β€” clean white bar with the patient identifier\n front and centre. Whole bar is still the drag handle; the\n interactive buttons stop drag via their own click handlers. */}\n <div data-drag-handle style={styles.titleBar}>\n {onBack && (\n <button\n onClick={onBack}\n style={styles.titleSquare}\n aria-label=\"Back to messages\"\n title=\"Back\"\n type=\"button\"\n >\n <BackIcon size={18} color={COLOR.neutral700} />\n </button>\n )}\n\n <div style={styles.titleCenter}>\n <h2 id={titleId} style={styles.patientName}>\n {patientData.patientName || titleText}\n </h2>\n {(patientData.labName || patientData.displayOrderId) && (\n <div style={styles.subRow}>\n {patientData.labName && <span>{patientData.labName}</span>}\n {patientData.labName && patientData.displayOrderId && (\n <span style={styles.subDot} aria-hidden=\"true\">Β·</span>\n )}\n {patientData.displayOrderId && (\n <span style={styles.mono}>\n #{patientData.displayOrderId.slice(-4)}\n </span>\n )}\n </div>\n )}\n </div>\n\n <div style={styles.titleActions}>\n <button\n onClick={() => {\n if (onMinimize) onMinimize();\n else setIsMinimized(!isMinimized);\n }}\n style={styles.titleSquare}\n aria-label={\n onMinimize\n ? 'Minimize chat'\n : isMinimized\n ? 'Expand chat'\n : 'Minimize chat'\n }\n title={\n onMinimize\n ? 'Minimize'\n : isMinimized\n ? 'Expand'\n : 'Minimize'\n }\n type=\"button\"\n >\n {onMinimize || !isMinimized ? (\n <MinimizeIcon size={18} color={COLOR.neutral700} />\n ) : (\n <ExpandIcon size={18} color={COLOR.neutral700} />\n )}\n </button>\n <button\n onClick={onClose}\n style={styles.titleSquare}\n aria-label=\"Close chat\"\n title=\"Close\"\n type=\"button\"\n >\n <CloseIcon size={18} color={COLOR.neutral700} />\n </button>\n </div>\n </div>\n\n {/* Panel content */}\n {!isMinimized && (\n <div style={styles.panelWrapper}>\n <CollabPanel\n orderId={orderId}\n patientData={patientData}\n participantIds={participantIds}\n hidePatientName\n onConversationChange={setLoadedConversation}\n />\n </div>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n position: 'fixed',\n zIndex: Z_INDEX.dialog,\n borderRadius: '20px',\n boxShadow: '0 20px 48px rgba(20, 21, 28, 0.16), 0 6px 16px rgba(20, 21, 28, 0.08)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n transition: 'height 0.2s ease',\n fontFamily: FONT_STACK,\n },\n titleBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `10px ${SPACE.S3}`,\n backgroundColor: COLOR.white,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n cursor: 'grab',\n userSelect: 'none',\n flexShrink: 0,\n },\n titleCenter: {\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n },\n patientName: {\n margin: 0,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '-0.01em',\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subDot: {\n color: COLOR.neutral400,\n },\n mono: {\n fontFamily:\n \"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontVariantNumeric: 'tabular-nums',\n },\n titleActions: {\n display: 'flex',\n gap: SPACE.S1,\n flexShrink: 0,\n },\n titleSquare: {\n width: '36px',\n height: '36px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: COLOR.neutral100,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n color: COLOR.neutral700,\n flexShrink: 0,\n },\n panelWrapper: {\n flex: 1,\n overflow: 'hidden',\n },\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n ConversationPreview,\n Message,\n Participant,\n PatientData,\n SendMessagePayload,\n} from '../core/types';\nimport { buildChannelName } from '../core/channelName';\n\ninterface UseInlineCollabOptions {\n orderId: string;\n patientData: PatientData;\n /** Participant IDs passed to the backend only when creating a new conversation */\n participantIds?: string[];\n /** Max messages to keep in inline state (default 5) */\n messageLimit?: number;\n}\n\ninterface UseInlineCollabReturn {\n hasConversation: boolean;\n messages: Message[];\n participants: Participant[];\n unreadCount: number;\n isLoading: boolean;\n isSubscribed: boolean;\n error: string | null;\n sendMessage: (body: string) => Promise<void>;\n /** Send a voice message β€” uploads the blob via config.onUploadFile first */\n sendAudioMessage: (audioBlob: Blob, duration: number) => Promise<void>;\n /** Attach to the DOM element that represents the row β€” drives lazy socket subscription */\n containerRef: (element: HTMLElement | null) => void;\n}\n\n/**\n * Lightweight hook for inline chat in table rows.\n *\n * Behavior:\n * - On mount: fetches preview (batched) β€” no socket work\n * - If conversation exists AND row becomes visible: joins Phoenix channel (real-time)\n * - If row scrolls out of view: leaves channel (frees resources)\n * - First sendMessage creates conversation atomically + starts real-time flow\n * - Subsequent sends go through the socket\n */\nexport function useInlineCollab({\n orderId,\n patientData,\n participantIds = [],\n messageLimit = 5,\n}: UseInlineCollabOptions): UseInlineCollabReturn {\n const {\n socket,\n config,\n requestPreview,\n invalidatePreview,\n createConversationWithMessage,\n } = useCollab();\n\n const [preview, setPreview] = useState<ConversationPreview | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const [participants, setParticipants] = useState<Participant[]>([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [isLoading, setIsLoading] = useState(true);\n const [isSubscribed, setIsSubscribed] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const elementRef = useRef<HTMLElement | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const subscribedConversationIdRef = useRef<string | null>(null);\n\n const trimToLimit = useCallback(\n (msgs: Message[]): Message[] =>\n msgs.length > messageLimit ? msgs.slice(msgs.length - messageLimit) : msgs,\n [messageLimit]\n );\n\n const buildName = useCallback(\n (): string => buildChannelName(patientData),\n [patientData]\n );\n\n // ── Fetch preview on mount (batched) ──\n useEffect(() => {\n let cancelled = false;\n\n const load = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const result = await requestPreview(orderId);\n if (cancelled) return;\n setPreview(result);\n if (result) {\n setMessages(trimToLimit(result.lastMessages));\n setParticipants(result.participants);\n setUnreadCount(result.unreadCount);\n }\n } catch (err) {\n if (cancelled) return;\n setError(err instanceof Error ? err.message : 'Failed to load preview');\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n load();\n return () => {\n cancelled = true;\n };\n }, [orderId, requestPreview, trimToLimit]);\n\n // ── Subscribe/unsubscribe socket based on visibility ──\n const subscribe = useCallback(\n (conversationId: string) => {\n if (subscribedConversationIdRef.current === conversationId) return;\n\n socket.joinConversation(conversationId, {\n onMessage: (msg) => {\n setMessages((prev) => trimToLimit([...prev, msg]));\n if (msg.senderId !== config.userId) {\n setUnreadCount((prev) => prev + 1);\n }\n },\n onUserJoined: (participant) => {\n setParticipants((prev) =>\n prev.some((p) => p.userId === participant.userId) ? prev : [...prev, participant]\n );\n },\n onUserLeft: (participant) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== participant.userId));\n },\n });\n\n subscribedConversationIdRef.current = conversationId;\n setIsSubscribed(true);\n },\n [socket, trimToLimit, config.userId]\n );\n\n const unsubscribe = useCallback(() => {\n const convId = subscribedConversationIdRef.current;\n if (convId) {\n socket.leaveConversation(convId);\n subscribedConversationIdRef.current = null;\n setIsSubscribed(false);\n }\n }, [socket]);\n\n // ── IntersectionObserver lifecycle ──\n const containerRef = useCallback(\n (element: HTMLElement | null) => {\n // Teardown old observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n elementRef.current = element;\n if (!element) return;\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n if (!entry) return;\n\n const convId = preview?.conversationId;\n if (!convId) return;\n\n if (entry.isIntersecting) {\n subscribe(convId);\n } else {\n unsubscribe();\n }\n },\n { threshold: 0.1 }\n );\n\n observerRef.current.observe(element);\n },\n [preview, subscribe, unsubscribe]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (observerRef.current) observerRef.current.disconnect();\n unsubscribe();\n };\n }, [unsubscribe]);\n\n // Re-attach observer when preview becomes available after element is mounted\n useEffect(() => {\n if (preview?.conversationId && elementRef.current && !observerRef.current) {\n containerRef(elementRef.current);\n }\n }, [preview, containerRef]);\n\n // ── Internal: send a message payload, lazy-creating the conversation on the first send ──\n const dispatchSend = useCallback(\n async (payload: SendMessagePayload) => {\n if (!preview) {\n // First message β€” create conversation + send atomically\n try {\n const result = await createConversationWithMessage(orderId, payload, {\n name: buildName(),\n participantIds,\n });\n\n const newPreview: ConversationPreview = {\n conversationId: result.conversation.id,\n orderId,\n messageCount: 1,\n unreadCount: 0,\n lastMessages: [result.message],\n participants: result.conversation.participants,\n name: result.conversation.name,\n };\n\n setPreview(newPreview);\n setMessages([result.message]);\n setParticipants(result.conversation.participants);\n invalidatePreview(orderId);\n\n if (elementRef.current) {\n subscribe(result.conversation.id);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send first message',\n details: err,\n });\n }\n return;\n }\n\n try {\n await socket.sendMessage(preview.conversationId, payload);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [\n preview,\n orderId,\n buildName,\n participantIds,\n createConversationWithMessage,\n invalidatePreview,\n subscribe,\n socket,\n config,\n ]\n );\n\n const sendMessage = useCallback(\n async (body: string) => {\n const trimmed = body.trim();\n if (!trimmed) return;\n await dispatchSend({ body: trimmed, type: 'text' });\n },\n [dispatchSend]\n );\n\n const sendAudioMessage = useCallback(\n async (audioBlob: Blob, duration: number) => {\n if (!config.onUploadFile) {\n setError('File upload is not configured');\n return;\n }\n try {\n const url = await config.onUploadFile(audioBlob, 'voice-message.webm');\n await dispatchSend({\n body: 'Voice message',\n type: 'audio',\n media_url: url,\n media_duration: duration,\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send voice message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send voice message',\n details: err,\n });\n }\n },\n [config, dispatchSend]\n );\n\n return {\n hasConversation: !!preview,\n messages,\n participants,\n unreadCount,\n isLoading,\n isSubscribed,\n error,\n sendMessage,\n sendAudioMessage,\n containerRef,\n };\n}\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useInlineCollab } from '../hooks/useInlineCollab';\n// MIC DISABLED β€” voice messaging temporarily removed. Imports kept for easy re-enable.\n// import { useAudioRecorder } from '../hooks/useAudioRecorder';\n// import { MicIcon } from './icons/MicIcon';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message, PatientData, UserRole } from '../core/types';\n\nensureGlobalStyles();\n\ninterface CollabInlineProps {\n orderId: string;\n patientData: PatientData;\n /** User IDs to invite when the first message creates the conversation */\n participantIds?: string[];\n /** Called when user clicks the expand button β€” host opens the floating popup */\n onExpand?: () => void;\n /** Max inline messages to show (default 5) */\n messageLimit?: number;\n /** Placeholder text for the input */\n placeholder?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Inline chat for table rows.\n *\n * Two states:\n * - No conversation yet: just an input bar (no socket, no preview)\n * - Conversation exists: last N messages + input + expand button\n *\n * Supports text and voice messages. File attachments and full chat features\n * stay in the floating popup / inbox.\n */\nexport function CollabInline({\n orderId,\n patientData,\n participantIds,\n onExpand,\n messageLimit = 5,\n placeholder = 'Type a message about this case...',\n className,\n style,\n}: CollabInlineProps) {\n const {\n hasConversation,\n messages,\n unreadCount,\n isLoading,\n isSubscribed,\n error,\n sendMessage,\n sendAudioMessage,\n containerRef,\n } = useInlineCollab({ orderId, patientData, participantIds, messageLimit });\n\n if (isLoading && !hasConversation) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={{ ...styles.container, ...style }}>\n <div style={styles.loadingState}>Loading...</div>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={{ ...styles.container, ...style }}>\n {hasConversation && messages.length > 0 && (\n <div style={styles.preview}>\n {messages.slice(-messageLimit).map((message) => (\n <InlineMessageRow key={message.id} message={message} />\n ))}\n </div>\n )}\n\n {error && <div style={styles.error}>{error}</div>}\n\n <InlineInputBar\n onSend={sendMessage}\n onSendAudio={sendAudioMessage}\n placeholder={placeholder}\n unreadCount={hasConversation ? unreadCount : 0}\n isLive={isSubscribed}\n showExpand={hasConversation && !!onExpand}\n onExpand={onExpand}\n />\n </div>\n );\n}\n\n// ─────────────────────────────────────────\n// Sub-components\n// ─────────────────────────────────────────\n\nfunction InlineMessageRow({ message }: { message: Message }) {\n if (message.type === 'system') {\n return (\n <div style={styles.systemRow}>\n <span style={styles.systemText}>{message.body}</span>\n </div>\n );\n }\n\n // Audio gets a compact play/pause + duration player inline\n if (message.type === 'audio' && message.mediaUrl) {\n return (\n <div style={styles.messageRow}>\n <RoleDot role={message.senderRole} />\n <span style={styles.senderName}>{message.senderName}:</span>\n <InlineAudioPlayer url={message.mediaUrl} duration={message.mediaDuration} />\n </div>\n );\n }\n\n const preview = renderMessagePreview(message);\n\n return (\n <div style={styles.messageRow}>\n <RoleDot role={message.senderRole} />\n <span style={styles.senderName}>{message.senderName}:</span>\n <span style={styles.messageText}>{preview}</span>\n </div>\n );\n}\n\nfunction RoleDot({ role }: { role: UserRole }) {\n // Cool-only palette β€” matches MessageBubble.roleColor() so the inline\n // preview reads the same as the full chat. See that helper for the\n // rationale (no greens / reds / purples on the chat surfaces).\n const colors: Record<UserRole, string> = {\n radiologist: '#4f46e5', // indigo\n lab: '#2563eb', // brand blue\n physician: '#0284c7', // sky\n admin: '#64748b', // slate\n };\n\n return <span style={{ ...styles.roleDot, backgroundColor: colors[role] }} />;\n}\n\n/**\n * Compact audio player designed to fit in a single inline row.\n * Shows just a play/pause toggle + duration. No scrubber.\n */\nfunction InlineAudioPlayer({ url, duration }: { url: string; duration?: number }) {\n const audioRef = useRef<HTMLAudioElement>(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n\n const toggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n const audio = audioRef.current;\n if (!audio) return;\n if (isPlaying) {\n audio.pause();\n } else {\n audio.play().catch(() => {\n // Silent fail β€” autoplay blocked, etc.\n });\n }\n },\n [isPlaying]\n );\n\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => {\n setIsPlaying(false);\n setCurrentTime(0);\n };\n const onTimeUpdate = () => setCurrentTime(audio.currentTime);\n\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('timeupdate', onTimeUpdate);\n\n return () => {\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('timeupdate', onTimeUpdate);\n };\n }, []);\n\n const total = duration ?? 0;\n const remaining = Math.max(0, total - Math.floor(currentTime));\n const displayTime = isPlaying ? remaining : total;\n\n return (\n <span style={styles.audioPlayer}>\n <button\n onClick={toggle}\n style={styles.audioButton}\n title={isPlaying ? 'Pause' : 'Play'}\n type=\"button\"\n >\n {isPlaying ? '⏸' : 'β–Ά'}\n </button>\n <span style={styles.audioWaveform}>\n {/* Purely decorative bars */}\n <span style={{ ...styles.waveBar, height: '40%' }} />\n <span style={{ ...styles.waveBar, height: '80%' }} />\n <span style={{ ...styles.waveBar, height: '60%' }} />\n <span style={{ ...styles.waveBar, height: '90%' }} />\n <span style={{ ...styles.waveBar, height: '50%' }} />\n <span style={{ ...styles.waveBar, height: '70%' }} />\n <span style={{ ...styles.waveBar, height: '40%' }} />\n </span>\n <span style={styles.audioDuration}>{formatDuration(displayTime)}</span>\n <audio ref={audioRef} src={url} preload=\"metadata\" />\n </span>\n );\n}\n\nfunction renderMessagePreview(message: Message): string {\n switch (message.type) {\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default:\n return message.body;\n }\n}\n\nfunction formatDuration(seconds: number): string {\n const safe = Math.max(0, Math.floor(seconds));\n const m = Math.floor(safe / 60);\n const s = safe % 60;\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\ninterface InlineInputBarProps {\n onSend: (body: string) => Promise<void>;\n /** @deprecated MIC DISABLED β€” kept in prop signature for backward compat. */\n onSendAudio?: (blob: Blob, duration: number) => Promise<void>;\n placeholder: string;\n unreadCount: number;\n isLive: boolean;\n showExpand: boolean;\n onExpand?: () => void;\n}\n\nfunction InlineInputBar({\n onSend,\n // MIC DISABLED β€” onSendAudio accepted but unused.\n // onSendAudio,\n placeholder,\n unreadCount,\n isLive,\n showExpand,\n onExpand,\n}: InlineInputBarProps) {\n const [text, setText] = useState('');\n const [isSending, setIsSending] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // MIC DISABLED β€” voice recorder hook + handlers not invoked. Restore by\n // uncommenting the destructure and handleStopRecording below (and the\n // imports at the top of the file).\n // const {\n // isRecording,\n // duration,\n // start: startRecording,\n // stop: stopRecording,\n // cancel: cancelRecording,\n // isSupported: micSupported,\n // error: micError,\n // } = useAudioRecorder();\n\n const handleSend = useCallback(async () => {\n const trimmed = text.trim();\n if (!trimmed || isSending) return;\n\n setIsSending(true);\n try {\n await onSend(trimmed);\n setText('');\n inputRef.current?.focus();\n } finally {\n setIsSending(false);\n }\n }, [text, isSending, onSend]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [handleSend]\n );\n\n // MIC DISABLED β€” audio stop handler unused. Restore alongside useAudioRecorder.\n // const handleStopRecording = useCallback(async () => {\n // const result = await stopRecording();\n // if (result) {\n // setIsSending(true);\n // try {\n // await onSendAudio(result.blob, result.duration);\n // } finally {\n // setIsSending(false);\n // }\n // }\n // }, [stopRecording, onSendAudio]);\n\n /* MIC DISABLED β€” recording mode branch removed. Original block kept here\n for easy re-enable when mic is restored:\n\n if (isRecording) {\n return (\n <div style={styles.recordingBar}>\n <span style={styles.recordingDot} />\n <span style={styles.recordingLabel}>Recording {formatDuration(duration)}</span>\n <button onClick={cancelRecording} style={styles.recordingCancel} title=\"Cancel recording\" type=\"button\">Cancel</button>\n <button onClick={handleStopRecording} style={styles.recordingSend} title=\"Send voice message\" type=\"button\">Send</button>\n </div>\n );\n }\n */\n\n return (\n <div style={styles.inputBar}>\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={isSending}\n style={styles.input}\n />\n\n {unreadCount > 0 && (\n <span style={styles.unreadBadge} title={`${unreadCount} unread`}>\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n\n {isLive && <span style={styles.liveDot} title=\"Live updates active\" />}\n\n {/* MIC DISABLED β€” mic button hidden. Original block:\n {micSupported && !text.trim() && (\n <button onClick={startRecording} disabled={isSending} style={styles.micButton} title=\"Record voice message\" type=\"button\">\n <MicIcon size={16} color=\"#374151\" />\n </button>\n )}\n */}\n\n {/* Send button β€” shown when there's text to send */}\n {text.trim() && (\n <button\n onClick={handleSend}\n disabled={isSending}\n style={styles.sendButton}\n title=\"Send message\"\n type=\"button\"\n >\n ➀\n </button>\n )}\n\n {showExpand && onExpand && (\n <button\n onClick={onExpand}\n style={styles.expandButton}\n title=\"Expand to full chat\"\n type=\"button\"\n >\n β›Ά\n </button>\n )}\n </div>\n );\n}\n\n// ─────────────────────────────────────────\n// Styles\n// ─────────────────────────────────────────\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n padding: `${SPACE.S1} ${SPACE.S2}`,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.md,\n fontFamily: FONT_STACK,\n },\n loadingState: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n textAlign: 'center',\n },\n error: {\n padding: `${SPACE.S1} ${SPACE.S2}`,\n marginBottom: SPACE.S1,\n fontSize: FONT_SIZE.xs,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n borderRadius: RADIUS.sm,\n },\n preview: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n marginBottom: SPACE.S1,\n paddingBottom: SPACE.S1,\n borderBottom: `1px solid ${COLOR.neutral100}`,\n },\n messageRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.xs,\n lineHeight: LINE_HEIGHT.normal,\n overflow: 'hidden',\n },\n roleDot: {\n flexShrink: 0,\n width: '6px',\n height: '6px',\n borderRadius: RADIUS.full,\n },\n senderName: {\n flexShrink: 0,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n messageText: {\n color: COLOR.neutral600,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n flex: 1,\n },\n systemRow: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral400,\n fontStyle: 'italic',\n textAlign: 'center',\n padding: '2px 0',\n },\n systemText: {\n opacity: 0.8,\n },\n // ── Audio player (inline) ──\n audioPlayer: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `2px ${SPACE.S2}`,\n borderRadius: RADIUS.lg,\n backgroundColor: COLOR.primaryBg,\n border: `1px solid ${COLOR.primaryBg}`,\n flex: 1,\n minWidth: 0,\n },\n audioButton: {\n width: '20px',\n height: '20px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.xs,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n audioWaveform: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '2px',\n height: SPACE.S4,\n flex: 1,\n minWidth: 0,\n },\n waveBar: {\n display: 'inline-block',\n width: '2px',\n borderRadius: '1px',\n backgroundColor: COLOR.primary,\n },\n audioDuration: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n fontVariantNumeric: 'tabular-nums',\n fontWeight: FONT_WEIGHT.medium,\n flexShrink: 0,\n },\n // ── Input bar ──\n inputBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n input: {\n flex: 1,\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.pill,\n outline: 'none',\n fontFamily: 'inherit',\n minWidth: 0,\n },\n unreadBadge: {\n flexShrink: 0,\n minWidth: '18px',\n height: '18px',\n padding: `0 ${SPACE.S1}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n borderRadius: RADIUS.pill,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n liveDot: {\n flexShrink: 0,\n width: '6px',\n height: '6px',\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.success,\n },\n micButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n backgroundColor: COLOR.neutral100,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n sendButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n expandButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n // ── Recording mode ──\n recordingBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S3}`,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.pill,\n },\n recordingDot: {\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.danger,\n flexShrink: 0,\n animation: 'pulse 1.5s infinite',\n },\n recordingLabel: {\n flex: 1,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n fontVariantNumeric: 'tabular-nums',\n },\n recordingCancel: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n flexShrink: 0,\n },\n recordingSend: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n flexShrink: 0,\n },\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { ConversationListItem } from '../core/types';\n\ninterface UseConversationListOptions {\n /**\n * When false, skips the initial auto-fetch. The caller can still invoke\n * `refresh()` manually (e.g. on user interaction). Defaults to true.\n */\n enabled?: boolean;\n}\n\ninterface UseConversationListReturn {\n conversations: ConversationListItem[];\n isLoading: boolean;\n error: string | null;\n refresh: () => Promise<void>;\n /** Filter conversations by query string (matches channel name + patient name) */\n filter: (query: string) => ConversationListItem[];\n /** Total unread across all conversations */\n totalUnread: number;\n}\n\n/**\n * Fetches the current user's full conversation list for the inbox.\n * Conversations are returned sorted by last activity (backend-sorted).\n *\n * Pass `{ enabled: false }` for lazy mode β€” useful when the list is behind\n * a click (e.g. a collapsed FAB panel) and you don't want to hit the API\n * until the user opens it.\n */\nexport function useConversationList(\n options?: UseConversationListOptions\n): UseConversationListReturn {\n const enabled = options?.enabled ?? true;\n const { fetchConversationList, config, totalUnread: serverTotalUnread } =\n useCollab();\n const [conversations, setConversations] = useState<ConversationListItem[]>([]);\n const [isLoading, setIsLoading] = useState(enabled);\n const [error, setError] = useState<string | null>(null);\n\n // Silent refresh (no spinner flash) β€” used for socket-driven resyncs so a\n // background update doesn't blink the list.\n const silentRefresh = useCallback(async () => {\n try {\n const list = await fetchConversationList();\n setConversations(list);\n } catch (err) {\n config.onError?.({\n code: 'LIST_ERROR',\n message: err instanceof Error ? err.message : 'Failed to load conversations',\n details: err,\n });\n }\n }, [fetchConversationList, config]);\n\n const refresh = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const list = await fetchConversationList();\n setConversations(list);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to load conversations';\n setError(msg);\n config.onError?.({\n code: 'LIST_ERROR',\n message: msg,\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [fetchConversationList, config]);\n\n useEffect(() => {\n if (!enabled) return;\n refresh();\n }, [enabled, refresh]);\n\n // Live resync: the server pushes an `unread_update` event on the user\n // notifications channel any time a message arrives, gets read, etc.\n // CollabProvider surfaces that as `serverTotalUnread`. When it changes\n // and the list is currently showing, pull fresh data silently so the\n // last-message / activity order / unread badges all stay in sync without\n // the user having to close and reopen the panel.\n //\n // Skip the first run β€” the main effect above already handled mount,\n // firing a silent refetch here on top would double-fetch.\n const hasHandledInitialUnreadRef = useRef(false);\n useEffect(() => {\n if (!enabled) return;\n if (!hasHandledInitialUnreadRef.current) {\n hasHandledInitialUnreadRef.current = true;\n return;\n }\n silentRefresh();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [serverTotalUnread, enabled]);\n\n const filter = useCallback(\n (query: string): ConversationListItem[] => {\n const q = query.trim().toLowerCase();\n if (!q) return conversations;\n return conversations.filter((c) => {\n const patient = c.patientSnapshot?.patientName?.toLowerCase() || '';\n const name = c.name.toLowerCase();\n return name.includes(q) || patient.includes(q);\n });\n },\n [conversations]\n );\n\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n\n return {\n conversations,\n isLoading,\n error,\n refresh,\n filter,\n totalUnread,\n };\n}\n","import React from 'react';\nimport type { ConversationListItem as ListItem, Message } from '../core/types';\nimport { formatInboxTimestamp } from '../core/dateLabels';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\n\ninterface ConversationListItemProps {\n item: ListItem;\n isSelected: boolean;\n onClick: () => void;\n className?: string;\n}\n\n/**\n * Single row in the inbox sidebar.\n *\n * Three-row layout (top-to-bottom):\n * 1. Patient/channel name + relative time\n * 2. Study type + monospace `MRN <patientId>` (surfaced from the\n * snapshot; either field is optional and the row collapses if both\n * are missing)\n * 3. Last message preview (sender prefix in stronger weight) + unread\n * count badge on the right\n *\n * Active row gets a 4px brand-color left-border accent + tinted background.\n * The avatar is a 52px **square** tile (16px rounded corners) with brand-\n * coloured fill and white initials β€” easier to scan than a circle at this\n * size and consistent across the inbox without depending on any case\n * status field we don't model.\n */\nexport function ConversationListItem({\n item,\n isSelected,\n onClick,\n className,\n}: ConversationListItemProps) {\n const hasUnread = item.unreadCount > 0;\n const displayName = item.name || item.patientSnapshot?.patientName || 'Unknown';\n const studyType = item.patientSnapshot?.studyType;\n const patientId = item.patientSnapshot?.patientId;\n const showStudyRow = !!(studyType || patientId);\n const initials = computeInitials(item.patientSnapshot?.patientName || displayName);\n\n return (\n <button\n className={className}\n onClick={onClick}\n style={{\n ...styles.container,\n ...(isSelected ? styles.selected : {}),\n }}\n type=\"button\"\n >\n {/* Avatar β€” square tile with rounded corners, brand-coloured */}\n <div style={styles.avatarWrapper}>\n {item.picture ? (\n <img src={item.picture} alt=\"\" style={styles.avatarImg} />\n ) : (\n <div style={styles.avatarTile} aria-hidden=\"true\">\n {initials}\n </div>\n )}\n </div>\n\n {/* Main content */}\n <div style={styles.content}>\n <div style={styles.topRow}>\n <span\n style={{\n ...styles.name,\n ...(hasUnread ? styles.nameUnread : {}),\n }}\n >\n {displayName}\n </span>\n <span\n style={{\n ...styles.time,\n ...(hasUnread ? styles.timeUnread : {}),\n }}\n >\n {formatInboxTimestamp(item.lastActivityAt)}\n </span>\n </div>\n\n {showStudyRow && (\n <div style={styles.studyRow}>\n {studyType && <span style={styles.studyType}>{studyType}</span>}\n {studyType && patientId && <span style={styles.studyDivider}>Β·</span>}\n {patientId && <span style={styles.studyId}>MRN {patientId}</span>}\n </div>\n )}\n\n <div style={styles.bottomRow}>\n <PreviewLine message={item.lastMessage} hasUnread={hasUnread} />\n {hasUnread && (\n <span style={styles.badge} aria-label={`${item.unreadCount} unread`}>\n {item.unreadCount > 99 ? '99+' : item.unreadCount}\n </span>\n )}\n </div>\n </div>\n </button>\n );\n}\n\nfunction PreviewLine({ message, hasUnread }: { message?: Message; hasUnread: boolean }) {\n if (!message) {\n return <span style={styles.preview}>No messages yet</span>;\n }\n if (message.type === 'system') {\n return <span style={styles.preview}>{message.body}</span>;\n }\n const text = previewText(message);\n const sender = message.senderName ? `${message.senderName.split(' ')[0]}:` : '';\n return (\n <span\n style={{\n ...styles.preview,\n ...(hasUnread ? styles.previewUnread : {}),\n }}\n >\n {sender && <span style={styles.previewSender}>{sender} </span>}\n {text}\n </span>\n );\n}\n\nfunction previewText(message: Message): string {\n switch (message.type) {\n case 'audio':\n return 'Voice message';\n case 'image':\n return message.fileName || 'Image';\n case 'file':\n return message.fileName || 'File';\n case 'deep_link':\n return message.body || 'Shared link';\n default: {\n const body = message.body || '';\n return body.length > 60 ? `${body.slice(0, 60)}…` : body;\n }\n }\n}\n\nfunction computeInitials(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((part) => part[0]?.toUpperCase() ?? '')\n .join('') || '?';\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '14px',\n width: '100%',\n padding: `14px ${SPACE.S5}`,\n minHeight: '84px',\n backgroundColor: 'transparent',\n border: 'none',\n borderLeft: '4px solid transparent',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'inherit',\n fontFamily: 'inherit',\n transition: 'background-color 120ms ease',\n },\n selected: {\n backgroundColor: COLOR.primaryBg,\n borderLeftColor: COLOR.primary,\n },\n avatarWrapper: {\n width: '52px',\n height: '52px',\n flexShrink: 0,\n },\n avatarImg: {\n width: '52px',\n height: '52px',\n borderRadius: RADIUS.xl,\n objectFit: 'cover' as const,\n boxShadow: 'inset 0 -2px 0 rgba(0, 0, 0, 0.08)',\n },\n avatarTile: {\n width: '52px',\n height: '52px',\n borderRadius: RADIUS.xl,\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '0.02em',\n boxShadow: 'inset 0 -2px 0 rgba(0, 0, 0, 0.08)',\n },\n content: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '3px',\n minWidth: 0,\n },\n topRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'baseline',\n gap: SPACE.S2,\n },\n name: {\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n nameUnread: {\n fontWeight: FONT_WEIGHT.bold,\n },\n time: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n timeUnread: {\n color: COLOR.primary,\n fontWeight: FONT_WEIGHT.semibold,\n },\n studyRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n minWidth: 0,\n },\n studyType: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n studyDivider: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral400,\n flexShrink: 0,\n },\n studyId: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n fontFamily:\n \"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n bottomRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: SPACE.S2,\n marginTop: '2px',\n },\n preview: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n previewSender: {\n color: COLOR.neutral700,\n fontWeight: FONT_WEIGHT.semibold,\n },\n previewUnread: {\n color: COLOR.neutral900,\n fontWeight: FONT_WEIGHT.medium,\n },\n badge: {\n minWidth: '22px',\n height: '22px',\n padding: '0 9px',\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.bold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n borderRadius: RADIUS.pill,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n};\n","import React from 'react';\n\nexport function SearchIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M20 20l-4-4\" />\n </svg>\n );\n}\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { ConversationListItem } from './ConversationListItem';\nimport { SearchIcon } from './icons/SearchIcon';\nimport { ChatIllustration } from './icons/ChatIllustration';\nimport { Spinner } from './Spinner';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { ConversationListItem as ListItem } from '../core/types';\n\ninterface ConversationListProps {\n conversations: ListItem[];\n selectedId: string | null;\n isLoading: boolean;\n error: string | null;\n onSelect: (item: ListItem) => void;\n className?: string;\n}\n\ntype Filter = 'all' | 'unread';\n\n/**\n * Scrollable inbox of conversations. Unread/All tabs (with count pills)\n * sit at the top, followed by a search field with a focus-within ring.\n * On first data load with any unread items the inbox auto-defaults to\n * the Unread tab so triage starts on what matters. Empty/loading/error\n * states are illustrated and descriptive rather than terse one-liners.\n */\nexport function ConversationList({\n conversations,\n selectedId,\n isLoading,\n error,\n onSelect,\n className,\n}: ConversationListProps) {\n const [query, setQuery] = useState('');\n const [filter, setFilter] = useState<Filter>('all');\n const [searchFocused, setSearchFocused] = useState(false);\n\n const unreadCount = useMemo(\n () => conversations.filter((c) => c.unreadCount > 0).length,\n [conversations]\n );\n\n // Auto-default to the Unread tab on first data load if there are\n // unread conversations β€” saves the user a click when they open the\n // inbox specifically to triage what's new. One-shot via a ref so we\n // never override a manual tab switch the user makes afterwards.\n const autoDefaultedRef = useRef(false);\n useEffect(() => {\n if (autoDefaultedRef.current) return;\n if (conversations.length === 0) return;\n autoDefaultedRef.current = true;\n if (unreadCount > 0) setFilter('unread');\n }, [conversations.length, unreadCount]);\n\n const filtered = useMemo(() => {\n let result = conversations;\n if (filter === 'unread') {\n result = result.filter((c) => c.unreadCount > 0);\n }\n const q = query.trim().toLowerCase();\n if (q) {\n result = result.filter((c) => {\n const name = c.name.toLowerCase();\n const patient = c.patientSnapshot?.patientName?.toLowerCase() || '';\n const studyType = c.patientSnapshot?.studyType?.toLowerCase() || '';\n const patientId = c.patientSnapshot?.patientId?.toLowerCase() || '';\n return (\n name.includes(q) ||\n patient.includes(q) ||\n studyType.includes(q) ||\n patientId.includes(q)\n );\n });\n }\n return result;\n }, [conversations, query, filter]);\n\n return (\n <div className={className} style={styles.container}>\n {/* Filter toggles β€” Unread first so it's the natural starting\n point when the inbox auto-defaults there on open. */}\n <div style={styles.tabs}>\n <TabButton\n label=\"Unread\"\n count={unreadCount}\n isActive={filter === 'unread'}\n onClick={() => setFilter('unread')}\n />\n <TabButton\n label=\"All\"\n count={conversations.length}\n isActive={filter === 'all'}\n onClick={() => setFilter('all')}\n />\n </div>\n\n {/* Search β€” focus-within glow */}\n <div\n style={{\n ...styles.search,\n ...(searchFocused ? styles.searchFocused : {}),\n }}\n >\n <span style={styles.searchIcon} aria-hidden=\"true\">\n <SearchIcon size={20} color={COLOR.neutral500} />\n </span>\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onFocus={() => setSearchFocused(true)}\n onBlur={() => setSearchFocused(false)}\n placeholder=\"Search by patient name or MRN\"\n aria-label=\"Search conversations\"\n style={styles.searchInput}\n />\n </div>\n\n {/* List */}\n <div style={styles.list}>\n {isLoading && (\n <div style={styles.loading}>\n <Spinner size={16} />\n <span>Loading conversations…</span>\n </div>\n )}\n\n {error && !isLoading && <div style={styles.errorState}>{error}</div>}\n\n {!isLoading && !error && filtered.length === 0 && (\n <EmptyState filter={filter} hasQuery={query.trim().length > 0} />\n )}\n\n {filtered.map((item) => (\n <ConversationListItem\n key={item.id}\n item={item}\n isSelected={selectedId === item.id}\n onClick={() => onSelect(item)}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction TabButton({\n label,\n count,\n isActive,\n onClick,\n}: {\n label: string;\n count: number;\n isActive: boolean;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n style={{\n ...styles.tab,\n ...(isActive ? styles.tabActive : {}),\n }}\n >\n <span>{label}</span>\n <span\n style={{\n ...styles.tabCount,\n ...(isActive ? styles.tabCountActive : {}),\n }}\n >\n {count}\n </span>\n </button>\n );\n}\n\nfunction EmptyState({ filter, hasQuery }: { filter: Filter; hasQuery: boolean }) {\n let title = 'No conversations yet';\n let subtitle = 'New chats will show up here as cases come in.';\n if (filter === 'unread') {\n title = 'No unread messages';\n subtitle = \"You're all caught up.\";\n } else if (hasQuery) {\n title = 'No conversations match';\n subtitle = 'Try a different search.';\n }\n return (\n <div style={styles.empty}>\n <ChatIllustration size={88} />\n <p style={styles.emptyTitle}>{title}</p>\n <p style={styles.emptySubtitle}>{subtitle}</p>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n },\n // Tabs sit at the top of the panel now (header section removed).\n // A bit more top padding so they don't crowd the top edge.\n tabs: {\n display: 'flex',\n gap: SPACE.S2,\n padding: `${SPACE.S5} ${SPACE.S5} ${SPACE.S2}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n flexShrink: 0,\n },\n tab: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S4}`,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n color: COLOR.neutral500,\n fontFamily: 'inherit',\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n transition: 'background-color 120ms ease, color 120ms ease',\n },\n tabActive: {\n backgroundColor: COLOR.primaryBg,\n color: COLOR.primary,\n },\n tabCount: {\n fontSize: FONT_SIZE.xs,\n fontVariantNumeric: 'tabular-nums',\n padding: '1px 8px',\n borderRadius: RADIUS.pill,\n backgroundColor: COLOR.neutral200,\n color: COLOR.neutral500,\n fontWeight: FONT_WEIGHT.semibold,\n },\n tabCountActive: {\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n },\n search: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n margin: `14px ${SPACE.S5} ${SPACE.S3}`,\n padding: `${SPACE.S3} 14px`,\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n transition: 'background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease',\n },\n searchFocused: {\n backgroundColor: COLOR.white,\n borderColor: COLOR.primary,\n boxShadow: `0 0 0 3px ${COLOR.primaryBg}`,\n },\n searchIcon: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n searchInput: {\n flex: 1,\n minWidth: 0,\n border: 'none',\n background: 'transparent',\n outline: 'none',\n fontFamily: 'inherit',\n fontSize: FONT_SIZE.md,\n color: COLOR.neutral900,\n },\n list: {\n flex: 1,\n overflowY: 'auto',\n padding: '4px 0 12px',\n },\n loading: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE.S2,\n padding: `44px ${SPACE.S5}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n errorState: {\n padding: SPACE.S4,\n margin: SPACE.S3,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.md,\n textAlign: 'center',\n },\n empty: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '44px 24px',\n textAlign: 'center',\n color: COLOR.neutral500,\n },\n emptyTitle: {\n margin: '12px 0 4px',\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n emptySubtitle: {\n margin: 0,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n maxWidth: '280px',\n lineHeight: LINE_HEIGHT.normal,\n },\n};\n","import React, { useEffect, useState } from 'react';\nimport { useConversationList } from '../hooks/useConversationList';\nimport { ConversationList } from './ConversationList';\nimport { CollabPanel } from './CollabPanel';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n SPACE,\n} from '../core/theme';\nimport type { ConversationListItem, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\n/** Width below which the inbox collapses to a single-pane list↔detail UX. */\nconst COMPACT_BREAKPOINT = 720;\n\ninterface CollabInboxProps {\n /** Optional: preselect a specific conversation (by conversation ID) */\n initialConversationId?: string;\n /** Optional callback when the user selects a conversation */\n onSelectConversation?: (item: ConversationListItem) => void;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Full-page inbox β€” WhatsApp-style sidebar of all user's conversations\n * with the selected conversation's CollabPanel on the right.\n *\n * Uses the same CollabPanel as the floating popup, so all features\n * (reply, pin, seen-by, DICOM, voice, attachments) are available.\n */\nexport function CollabInbox({\n initialConversationId,\n onSelectConversation,\n className,\n style,\n}: CollabInboxProps) {\n const { conversations, isLoading, error } = useConversationList();\n const [selectedId, setSelectedId] = useState<string | null>(initialConversationId ?? null);\n const [isCompact, setIsCompact] = useState<boolean>(() =>\n typeof window === 'undefined' ? false : window.innerWidth < COMPACT_BREAKPOINT\n );\n\n // Track viewport breakpoint at runtime β€” we keep both list and detail\n // mounted in wide layouts but render only one at a time on narrow screens\n // so phone/tablet users don't lose half the viewport to a 320px sidebar.\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia(`(max-width: ${COMPACT_BREAKPOINT - 1}px)`);\n const sync = () => setIsCompact(mq.matches);\n sync();\n mq.addEventListener('change', sync);\n return () => mq.removeEventListener('change', sync);\n }, []);\n\n const selected = conversations.find((c) => c.id === selectedId) || null;\n\n const handleSelect = (item: ConversationListItem) => {\n setSelectedId(item.id);\n onSelectConversation?.(item);\n };\n\n // In compact mode we toggle between list and detail. The \"back\" affordance\n // simply clears the selection so the list re-renders full-width.\n const showDetail = !isCompact || (isCompact && !!selected);\n const showList = !isCompact || (isCompact && !selected);\n\n return (\n <div\n className={[ROOT_CLASS, className].filter(Boolean).join(' ')}\n style={{ ...styles.container, ...style }}\n >\n {showList && (\n <div style={isCompact ? styles.sidebarCompact : styles.sidebar}>\n <ConversationList\n conversations={conversations}\n selectedId={selectedId}\n isLoading={isLoading}\n error={error}\n onSelect={handleSelect}\n />\n </div>\n )}\n\n {showDetail && (\n <div style={isCompact ? styles.mainCompact : styles.main}>\n {selected ? (\n <CollabPanel\n key={selected.id}\n orderId={selected.orderId}\n patientData={buildPatientData(selected)}\n showSeenBy={true}\n style={styles.panel}\n onBack={isCompact ? () => setSelectedId(null) : undefined}\n />\n ) : (\n <EmptyState hasAny={conversations.length > 0} />\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction buildPatientData(item: ConversationListItem): PatientData {\n // The server-stored channel name (item.name) is always in the canonical\n // \"<patient> - <lab> - <last4>\" form, so parse it and merge with the\n // patient snapshot. Older snapshots created before the backend started\n // resolving labName via UserLookup lack the lab field β€” without this\n // merge, the header would render \"<patient> - - <last4>\" while the\n // inbox row (which uses item.name) shows the correct lab name.\n const parsed = parseChannelName(item.name, item.orderId);\n\n if (item.patientSnapshot) {\n return {\n ...item.patientSnapshot,\n labName: item.patientSnapshot.labName ?? parsed.labName,\n displayOrderId: item.patientSnapshot.displayOrderId ?? parsed.displayOrderId,\n };\n }\n\n return parsed;\n}\n\nfunction parseChannelName(name: string, orderId: string): PatientData {\n // Format (from buildChannelName): \"<patient> - <lab> - <last4>\"\n const parts = name.split(' - ');\n if (parts.length >= 3) {\n const last4 = parts[parts.length - 1];\n const labName = parts[parts.length - 2];\n const patientName = parts.slice(0, parts.length - 2).join(' - ');\n return {\n patientName,\n labName: labName || undefined,\n orderId,\n displayOrderId: last4,\n };\n }\n\n return {\n patientName: name,\n orderId,\n };\n}\n\nfunction EmptyState({ hasAny }: { hasAny: boolean }) {\n return (\n <div style={styles.empty}>\n <div style={styles.emptyIcon}>πŸ’¬</div>\n <h3 style={styles.emptyTitle}>\n {hasAny ? 'Select a conversation' : 'No conversations yet'}\n </h3>\n <p style={styles.emptySubtitle}>\n {hasAny\n ? 'Pick a patient from the list to start collaborating'\n : 'Conversations appear here once you start messaging about a case'}\n </p>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n height: '100%',\n width: '100%',\n backgroundColor: COLOR.white,\n fontFamily: FONT_STACK,\n },\n sidebar: {\n width: '320px',\n minWidth: '280px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n },\n sidebarCompact: {\n width: '100%',\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n },\n main: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n padding: SPACE.S3,\n backgroundColor: COLOR.neutral100,\n },\n mainCompact: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n backgroundColor: COLOR.neutral100,\n },\n panel: {\n height: '100%',\n width: '100%',\n },\n empty: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S6}`,\n textAlign: 'center',\n },\n emptyIcon: {\n fontSize: FONT_SIZE.xxl,\n marginBottom: SPACE.S3,\n },\n emptyTitle: {\n margin: `0 0 ${SPACE.S2}`,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n emptySubtitle: {\n margin: 0,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n maxWidth: '320px',\n },\n};\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { Message } from '../core/types';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\n\ninterface UseMessagesOptions {\n conversationId: string | null;\n /** Initial page size (default 30) */\n initialLimit?: number;\n}\n\ninterface UseMessagesReturn {\n messages: Message[];\n isLoading: boolean;\n hasMore: boolean;\n error: string | null;\n loadMore: () => Promise<void>;\n addMessage: (message: Message) => void;\n updateMessageReadBy: (messageId: string, userId: string) => void;\n reset: () => void;\n}\n\n/**\n * Standalone hook for message history management.\n * Use this if you need message data outside of useConversation\n * (e.g. building a completely custom UI).\n */\nexport function useMessages({\n conversationId,\n initialLimit = MESSAGES_PAGE_SIZE,\n}: UseMessagesOptions): UseMessagesReturn {\n const { fetchMessages, config } = useCollab();\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const loadedRef = useRef<string | null>(null);\n\n // Load initial messages when conversation changes\n useEffect(() => {\n if (!conversationId) {\n setMessages([]);\n setHasMore(false);\n loadedRef.current = null;\n return;\n }\n\n if (loadedRef.current === conversationId) return;\n\n let cancelled = false;\n\n const loadInitial = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const initial = await fetchMessages(conversationId, { limit: initialLimit });\n if (cancelled) return;\n setMessages(initial);\n setHasMore(initial.length >= initialLimit);\n loadedRef.current = conversationId;\n } catch (err) {\n if (cancelled) return;\n const msg = err instanceof Error ? err.message : 'Failed to load messages';\n setError(msg);\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load messages',\n details: err,\n });\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n loadInitial();\n\n return () => {\n cancelled = true;\n };\n }, [conversationId, initialLimit, fetchMessages, config]);\n\n const loadMore = useCallback(async () => {\n if (!conversationId || !hasMore || isLoading) return;\n\n const oldestId = messages[0]?.id;\n setIsLoading(true);\n try {\n const older = await fetchMessages(conversationId, {\n limit: initialLimit,\n before: oldestId,\n });\n setMessages((prev) => [...older, ...prev]);\n setHasMore(older.length >= initialLimit);\n } catch (err) {\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load older messages',\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [conversationId, hasMore, isLoading, messages, initialLimit, fetchMessages, config]);\n\n const addMessage = useCallback((message: Message) => {\n setMessages((prev) => [...prev, message]);\n }, []);\n\n const updateMessageReadBy = useCallback((messageId: string, userId: string) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === messageId && !(msg.readBy ?? []).includes(userId)\n ? { ...msg, readBy: [...(msg.readBy ?? []), userId] }\n : msg\n )\n );\n }, []);\n\n const reset = useCallback(() => {\n setMessages([]);\n setHasMore(true);\n setError(null);\n loadedRef.current = null;\n }, []);\n\n return {\n messages,\n isLoading,\n hasMore,\n error,\n loadMore,\n addMessage,\n updateMessageReadBy,\n reset,\n };\n}\n","import { useState, useRef, useCallback } from 'react';\nimport { AUDIO_MIME_TYPE } from '../core/constants';\n\ninterface UseAudioRecorderReturn {\n /** Whether the mic is currently recording */\n isRecording: boolean;\n /** Recording duration in seconds (updates every second while recording) */\n duration: number;\n /** Start recording from the microphone */\n start: () => Promise<void>;\n /** Stop recording and return the audio blob */\n stop: () => Promise<{ blob: Blob; duration: number } | null>;\n /** Cancel recording without producing output */\n cancel: () => void;\n /** Whether the browser supports audio recording */\n isSupported: boolean;\n /** Error message if recording fails */\n error: string | null;\n}\n\n/**\n * Wraps the browser MediaRecorder API for voice message recording.\n * Returns a blob suitable for uploading via config.onUploadFile.\n */\nexport function useAudioRecorder(): UseAudioRecorderReturn {\n const [isRecording, setIsRecording] = useState(false);\n const [duration, setDuration] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const chunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const startTimeRef = useRef<number>(0);\n const resolveRef = useRef<((value: { blob: Blob; duration: number } | null) => void) | null>(null);\n\n const isSupported =\n typeof window !== 'undefined' &&\n typeof navigator !== 'undefined' &&\n !!navigator.mediaDevices?.getUserMedia &&\n !!window.MediaRecorder;\n\n const cleanup = useCallback(() => {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n\n mediaRecorderRef.current = null;\n chunksRef.current = [];\n setIsRecording(false);\n setDuration(0);\n }, []);\n\n const start = useCallback(async () => {\n if (!isSupported) {\n setError('Audio recording is not supported in this browser');\n return;\n }\n\n try {\n setError(null);\n chunksRef.current = [];\n\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Pick the best supported MIME type\n const mimeType = MediaRecorder.isTypeSupported(AUDIO_MIME_TYPE)\n ? AUDIO_MIME_TYPE\n : MediaRecorder.isTypeSupported('audio/webm')\n ? 'audio/webm'\n : 'audio/mp4';\n\n const recorder = new MediaRecorder(stream, { mimeType });\n mediaRecorderRef.current = recorder;\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunksRef.current.push(event.data);\n }\n };\n\n recorder.onerror = () => {\n setError('Recording failed');\n cleanup();\n resolveRef.current?.(null);\n resolveRef.current = null;\n };\n\n recorder.onstop = () => {\n const finalDuration = Math.round((Date.now() - startTimeRef.current) / 1000);\n const blob = new Blob(chunksRef.current, { type: mimeType });\n\n cleanup();\n resolveRef.current?.({ blob, duration: finalDuration });\n resolveRef.current = null;\n };\n\n recorder.start(250); // collect data every 250ms\n startTimeRef.current = Date.now();\n setIsRecording(true);\n\n // Update duration counter every second\n timerRef.current = setInterval(() => {\n const elapsed = Math.round((Date.now() - startTimeRef.current) / 1000);\n setDuration(elapsed);\n }, 1000);\n } catch (err) {\n if (err instanceof DOMException && err.name === 'NotAllowedError') {\n setError('Microphone access denied. Please allow microphone permissions.');\n } else {\n setError('Failed to start recording');\n }\n cleanup();\n }\n }, [isSupported, cleanup]);\n\n const stop = useCallback(async (): Promise<{ blob: Blob; duration: number } | null> => {\n return new Promise((resolve) => {\n if (!mediaRecorderRef.current || mediaRecorderRef.current.state === 'inactive') {\n resolve(null);\n return;\n }\n\n resolveRef.current = resolve;\n mediaRecorderRef.current.stop();\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {\n // Remove onstop handler to avoid producing output\n mediaRecorderRef.current.onstop = null;\n mediaRecorderRef.current.stop();\n }\n cleanup();\n resolveRef.current?.(null);\n resolveRef.current = null;\n }, [cleanup]);\n\n return {\n isRecording,\n duration,\n start,\n stop,\n cancel,\n isSupported,\n error,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\n\ninterface UseUnreadCountReturn {\n /** Total unread messages across all conversations */\n totalUnread: number;\n /** Get unread count for a specific conversation */\n getCountForConversation: (conversationId: string) => number;\n /** Manually clear unread count for a conversation (e.g. when user opens it) */\n clearForConversation: (conversationId: string) => void;\n}\n\n/**\n * Tracks unread message counts.\n * Counts are pushed from the server via the user channel (no polling).\n */\nexport function useUnreadCount(): UseUnreadCountReturn {\n const { socket, totalUnread } = useCollab();\n const [counts, setCounts] = useState<Record<string, number>>({});\n\n useEffect(() => {\n socket.onUnreadCountUpdate((serverCounts) => {\n setCounts(serverCounts);\n });\n }, [socket]);\n\n const getCountForConversation = useCallback(\n (conversationId: string): number => {\n return counts[conversationId] ?? 0;\n },\n [counts]\n );\n\n const clearForConversation = useCallback((conversationId: string) => {\n setCounts((prev) => {\n const next = { ...prev };\n delete next[conversationId];\n return next;\n });\n }, []);\n\n return {\n totalUnread,\n getCountForConversation,\n clearForConversation,\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { Message } from '../core/types';\n\ninterface UsePinnedMessagesOptions {\n conversationId: string | null;\n /** Initial pinned messages from preview/initial load (avoids extra fetch) */\n initial?: Message[];\n}\n\ninterface UsePinnedMessagesReturn {\n pinnedMessages: Message[];\n isLoading: boolean;\n error: string | null;\n pin: (messageId: string) => Promise<void>;\n unpin: (messageId: string) => Promise<void>;\n /** Handlers to wire to socket pin/unpin events */\n handlePinned: (message: Message) => void;\n handleUnpinned: (messageId: string) => void;\n refresh: () => Promise<void>;\n}\n\n/**\n * Manages pinned messages for a conversation.\n * Backend enforces MAX_PINNED_MESSAGES (3) β€” attempting to pin a 4th returns an error.\n */\nexport function usePinnedMessages({\n conversationId,\n initial = [],\n}: UsePinnedMessagesOptions): UsePinnedMessagesReturn {\n const { pinMessage, unpinMessage, fetchPinnedMessages, config } = useCollab();\n const [pinnedMessages, setPinnedMessages] = useState<Message[]>(initial);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n if (!conversationId) return;\n setIsLoading(true);\n setError(null);\n try {\n const pinned = await fetchPinnedMessages(conversationId);\n setPinnedMessages(pinned);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to load pinned messages';\n setError(msg);\n } finally {\n setIsLoading(false);\n }\n }, [conversationId, fetchPinnedMessages]);\n\n // Only auto-fetch if we don't have initial data\n useEffect(() => {\n if (conversationId && initial.length === 0) {\n refresh();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [conversationId]);\n\n const pin = useCallback(\n async (messageId: string) => {\n if (!conversationId) return;\n setError(null);\n try {\n await pinMessage(conversationId, messageId);\n // Server broadcasts message:pinned β€” handled via handlePinned\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to pin message';\n setError(msg);\n config.onError?.({\n code: 'PIN_ERROR',\n message: msg,\n details: err,\n });\n }\n },\n [conversationId, pinMessage, config]\n );\n\n const unpin = useCallback(\n async (messageId: string) => {\n if (!conversationId) return;\n setError(null);\n try {\n await unpinMessage(conversationId, messageId);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to unpin message';\n setError(msg);\n config.onError?.({\n code: 'UNPIN_ERROR',\n message: msg,\n details: err,\n });\n }\n },\n [conversationId, unpinMessage, config]\n );\n\n const handlePinned = useCallback((message: Message) => {\n setPinnedMessages((prev) => {\n if (prev.some((m) => m.id === message.id)) return prev;\n return [...prev, message];\n });\n }, []);\n\n const handleUnpinned = useCallback((messageId: string) => {\n setPinnedMessages((prev) => prev.filter((m) => m.id !== messageId));\n }, []);\n\n return {\n pinnedMessages,\n isLoading,\n error,\n pin,\n unpin,\n handlePinned,\n handleUnpinned,\n refresh,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/constants.ts","../src/core/caseConvert.ts","../src/core/socket.ts","../src/core/theme.ts","../src/core/styles.ts","../src/context/CollabProvider.tsx","../src/core/channelName.ts","../src/hooks/useConversation.ts","../src/hooks/useChannelSettings.ts","../src/hooks/useDeepLinks.ts","../src/components/icons/DicomIcon.tsx","../src/components/icons/PeopleIcon.tsx","../src/components/icons/BackIcon.tsx","../src/components/PatientHeader.tsx","../src/components/ReplyQuoteBlock.tsx","../src/components/SeenByIndicator.tsx","../src/components/icons/ReplyIcon.tsx","../src/components/icons/PinIcon.tsx","../src/components/icons/CopyIcon.tsx","../src/components/icons/MoreIcon.tsx","../src/components/MessageActionsMenu.tsx","../src/components/icons/FileIcon.tsx","../src/components/icons/AlertIcon.tsx","../src/components/Spinner.tsx","../src/components/MessageBubble.tsx","../src/components/icons/ChatIllustration.tsx","../src/core/dateLabels.ts","../src/components/MessageList.tsx","../src/components/ReplyPreview.tsx","../src/components/icons/AttachIcon.tsx","../src/components/icons/SendIcon.tsx","../src/components/icons/CloseIcon.tsx","../src/components/MessageInput.tsx","../src/components/ParticipantsList.tsx","../src/components/ChannelSettings.tsx","../src/components/PinnedMessagesBar.tsx","../src/components/Toast.tsx","../src/components/CollabPanel.tsx","../src/components/icons/MinimizeIcon.tsx","../src/components/CollabPopup.tsx","../src/hooks/useInlineCollab.ts","../src/components/CollabInline.tsx","../src/hooks/useConversationList.ts","../src/components/ConversationListItem.tsx","../src/components/icons/SearchIcon.tsx","../src/components/ConversationList.tsx","../src/components/CollabInbox.tsx","../src/hooks/useMessages.ts","../src/hooks/useAudioRecorder.ts","../src/hooks/useUnreadCount.ts","../src/hooks/usePinnedMessages.ts"],"names":["Socket","channel","Presence","createContext","useContext","useState","useRef","useEffect","useCallback","jsx","jsxs","styles","useLayoutEffect","menu","createPortal","escapeRegex","forwardRef","MessageList","useImperativeHandle","React","RoleBadge","Fragment","useId","formatDuration","computeInitials","useMemo","EmptyState"],"mappings":"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","file":"index.js","sourcesContent":["/** Phoenix channel event names β€” must match backend channel implementation */\nexport const EVENTS = {\n MESSAGE_NEW: 'message:new',\n MESSAGE_READ: 'message:read',\n MESSAGE_PINNED: 'message:pinned',\n MESSAGE_UNPINNED: 'message:unpinned',\n USER_TYPING: 'user:typing',\n USER_JOINED: 'user:joined',\n USER_LEFT: 'user:left',\n CHANNEL_UPDATED: 'channel:updated',\n CHANNEL_DELETED: 'channel:deleted',\n PRESENCE_STATE: 'presence_state',\n PRESENCE_DIFF: 'presence_diff',\n} as const;\n\n/** Maximum number of pinned messages allowed per conversation */\nexport const MAX_PINNED_MESSAGES = 3;\n\n/** Message types */\nexport const MESSAGE_TYPES = {\n TEXT: 'text',\n AUDIO: 'audio',\n IMAGE: 'image',\n FILE: 'file',\n SYSTEM: 'system',\n DEEP_LINK: 'deep_link',\n} as const;\n\n/** Deep link protocol prefix */\nexport const DEEP_LINK_PREFIX = 'natoe://';\n\n/** Typing indicator debounce in ms */\nexport const TYPING_DEBOUNCE_MS = 2000;\n\n/** Messages to load per page when scrolling back */\nexport const MESSAGES_PAGE_SIZE = 30;\n\n/** Supported audio MIME type for recording */\nexport const AUDIO_MIME_TYPE = 'audio/webm;codecs=opus';\n\n/** Supported image types for attachments */\nexport const SUPPORTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];\n\n/** Max file size in bytes (20MB) */\nexport const MAX_FILE_SIZE = 20 * 1024 * 1024;\n","/**\n * Recursively converts object keys from snake_case to camelCase.\n *\n * Used at every backend boundary (REST responses, socket events) to bridge\n * the Phoenix (snake_case) β†’ TypeScript (camelCase) gap.\n *\n * Idempotent β€” keys already in camelCase stay unchanged (no underscores to\n * convert). Arrays and primitives pass through untouched.\n */\nexport function snakeToCamel<T = unknown>(input: unknown): T {\n if (Array.isArray(input)) {\n return input.map((item) => snakeToCamel(item)) as unknown as T;\n }\n\n if (input !== null && typeof input === 'object') {\n const source = input as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n const camelKey = toCamelKey(key);\n out[camelKey] = snakeToCamel(source[key]);\n }\n return out as T;\n }\n\n return input as T;\n}\n\nfunction toCamelKey(key: string): string {\n if (!key.includes('_')) return key;\n return key.replace(/_([a-zA-Z0-9])/g, (_, c: string) => c.toUpperCase());\n}\n","import { Socket, Channel, Presence } from 'phoenix';\nimport type {\n CollabConfig,\n Message,\n Conversation,\n Participant,\n SendMessagePayload,\n TypingEvent,\n ChannelUpdatePayload,\n InviteUserPayload,\n} from './types';\nimport { EVENTS } from './constants';\nimport { snakeToCamel } from './caseConvert';\n\ntype MessageCallback = (message: Message) => void;\ntype TypingCallback = (event: TypingEvent) => void;\ntype ParticipantCallback = (participant: Participant) => void;\ntype ChannelUpdateCallback = (conversation: Partial<Conversation>) => void;\ntype PresenceCallback = (presences: Record<string, { userId: string; isOnline: boolean }>) => void;\n\ninterface ConversationCallbacks {\n onMessage?: MessageCallback;\n onTyping?: TypingCallback;\n onUserJoined?: ParticipantCallback;\n onUserLeft?: ParticipantCallback;\n onChannelUpdated?: ChannelUpdateCallback;\n onChannelDeleted?: () => void;\n onPresence?: PresenceCallback;\n onMessageRead?: (data: { messageId: string; userId: string }) => void;\n onMessagePinned?: (message: Message) => void;\n onMessageUnpinned?: (data: { messageId: string }) => void;\n}\n\n/**\n * Per-channel state held in the `channels` map.\n * `subscribers` is a refcount of live `joinConversation()` callers; the\n * underlying Phoenix channel is only `.leave()`'d when it drops to zero.\n */\ninterface ChannelEntry {\n channel: Channel;\n subscribers: number;\n presence: Presence | null;\n}\n\n/**\n * Returned by `joinConversation()`. Each caller gets its own handle and\n * its own bound listeners β€” calling `release()` unbinds only THIS\n * subscriber's listeners. The channel only actually leaves the server\n * when the last subscriber releases.\n */\nexport interface ChannelSubscription {\n /** Underlying Phoenix channel β€” callers that need to push/observe directly. */\n channel: Channel;\n /** Drop this subscriber. Idempotent β€” safe to call twice. */\n release: () => void;\n}\n\n/**\n * Manages Phoenix WebSocket connection and channel subscriptions.\n * One instance per authenticated user session.\n */\nexport class CollabSocket {\n private socket: Socket | null = null;\n /**\n * Conversation channels keyed by id. Each entry is reference-counted so\n * multiple surfaces (e.g. inline chat + expanded panel mounted at once\n * for the same conversation) can coexist without one's `leaveConversation`\n * tearing the channel out from under the other. See `joinConversation`\n * and the returned `ChannelSubscription.release`.\n */\n private channels: Map<string, ChannelEntry> = new Map();\n private presences: Map<string, Presence> = new Map();\n private userChannel: Channel | null = null;\n private config: CollabConfig | null = null;\n private onUnreadUpdate: ((counts: Record<string, number>) => void) | null = null;\n\n /** Connect to Phoenix WebSocket server. Idempotent β€” safe to call when\n * the token becomes available later (e.g. after async login) without\n * stacking up multiple open sockets. */\n connect(config: CollabConfig): void {\n this.config = config;\n\n // No token means the host hasn't finished login yet. Skip the connect\n // so we don't churn through reconnect attempts that the server would\n // reject with 1006 anyway. The host re-calls connect() once auth lands.\n if (!config.getToken()) {\n return;\n }\n\n // If a prior (live or half-dead) socket exists, retire it before\n // creating a new one. Otherwise the old heartbeat / channels leak.\n if (this.socket) {\n if (this.socket.isConnected()) return;\n try {\n this.socket.disconnect();\n } catch {\n // best-effort; we're about to replace it anyway\n }\n this.channels.clear();\n this.presences.clear();\n this.userChannel = null;\n }\n\n this.socket = new Socket(config.socketUrl, {\n params: () => ({ token: config.getToken() }),\n });\n\n // Phoenix's onError hands us the native WebSocket error/close event. We\n // forward whatever useful fields the browser gave us so failures like a\n // 403 handshake (bad token / missing Redis session) can be distinguished\n // from transport drops instead of all showing as \"error undefined\".\n this.socket.onError((err) => {\n const closeEvent = err as unknown as CloseEvent | undefined;\n config.onError?.({\n code: 'SOCKET_ERROR',\n message: 'WebSocket connection error',\n details: closeEvent\n ? {\n type: closeEvent.type,\n code: closeEvent.code,\n reason: closeEvent.reason,\n wasClean: closeEvent.wasClean,\n }\n : err,\n });\n });\n\n this.socket.onClose((event) => {\n // Code 1006 = abnormal closure (no close frame β€” usually means the\n // server rejected the upgrade, e.g. auth failed before handshake).\n // Code 1000 = normal; code 1011 = server error.\n config.onError?.({\n code: 'SOCKET_CLOSED',\n message: `Socket closed (code ${event?.code ?? 'unknown'})`,\n details: event\n ? { code: event.code, reason: event.reason, wasClean: event.wasClean }\n : undefined,\n });\n });\n\n this.socket.connect();\n this.joinUserChannel();\n }\n\n /** Subscribe to user-level events (unread counts, notifications) */\n private joinUserChannel(): void {\n if (!this.socket || !this.config) return;\n\n // Topic has no user_id suffix β€” backend derives it from the authenticated socket.\n // This avoids any mismatch between client-side stored IDs and the token's claims.\n this.userChannel = this.socket.channel('user_notifications', {});\n\n this.userChannel.on('unread_update', (payload: Record<string, number>) => {\n this.onUnreadUpdate?.(payload);\n });\n\n this.userChannel\n .join()\n .receive('ok', () => {\n // connected to user channel\n })\n .receive('error', (reason) => {\n this.config?.onError?.({\n code: 'USER_CHANNEL_ERROR',\n message: 'Failed to join user channel',\n details: reason,\n });\n });\n }\n\n /** Register callback for unread count changes */\n onUnreadCountUpdate(callback: (counts: Record<string, number>) => void): void {\n this.onUnreadUpdate = callback;\n }\n\n /**\n * Join a conversation channel and subscribe to events.\n *\n * Reference-counted: multiple callers can join the same conversation\n * (e.g. inline preview + expanded panel mounted side-by-side). Each\n * call binds its own listeners and gets back a `ChannelSubscription`.\n * The underlying channel only `.leave()`s the server when the LAST\n * subscriber calls `release()`.\n */\n joinConversation(\n conversationId: string,\n callbacks: ConversationCallbacks\n ): ChannelSubscription | null {\n if (!this.socket) return null;\n\n // Get-or-create the channel entry. Channel is joined exactly once;\n // subsequent subscribers just bump the refcount and bind their own\n // listeners on the existing Phoenix Channel object.\n let entry = this.channels.get(conversationId);\n if (!entry) {\n const channel = this.socket.channel(`conversation:${conversationId}`, {});\n channel\n .join()\n .receive('ok', () => {\n // successfully joined conversation channel\n })\n .receive('error', (reason: unknown) => {\n this.config?.onError?.({\n code: 'CHANNEL_JOIN_ERROR',\n message: `Failed to join conversation ${conversationId}`,\n details: reason,\n });\n });\n entry = { channel, subscribers: 0, presence: null };\n this.channels.set(conversationId, entry);\n }\n\n const channel = entry.channel;\n\n // Bind THIS subscriber's listeners. Phoenix's `channel.on` returns a\n // Ref we can later pass to `channel.off` to unbind only this caller's\n // listeners, leaving sibling subscribers' bindings intact.\n const refs: Array<{ event: string; ref: number }> = [];\n const bind = <T>(event: string, fn: (payload: T) => void) => {\n const ref = channel.on(event, fn as (payload: unknown) => void);\n refs.push({ event, ref });\n };\n\n if (callbacks.onMessage) {\n bind<unknown>(EVENTS.MESSAGE_NEW, (payload) => {\n callbacks.onMessage!(snakeToCamel<Message>(payload));\n });\n }\n if (callbacks.onTyping) {\n bind<unknown>(EVENTS.USER_TYPING, (payload) => {\n callbacks.onTyping!(snakeToCamel<TypingEvent>(payload));\n });\n }\n if (callbacks.onUserJoined) {\n bind<unknown>(EVENTS.USER_JOINED, (payload) => {\n callbacks.onUserJoined!(snakeToCamel<Participant>(payload));\n });\n }\n if (callbacks.onUserLeft) {\n bind<unknown>(EVENTS.USER_LEFT, (payload) => {\n callbacks.onUserLeft!(snakeToCamel<Participant>(payload));\n });\n }\n if (callbacks.onChannelUpdated) {\n bind<unknown>(EVENTS.CHANNEL_UPDATED, (payload) => {\n callbacks.onChannelUpdated!(snakeToCamel<Partial<Conversation>>(payload));\n });\n }\n if (callbacks.onChannelDeleted) {\n bind<unknown>(EVENTS.CHANNEL_DELETED, () => {\n callbacks.onChannelDeleted!();\n });\n }\n if (callbacks.onMessageRead) {\n bind<unknown>(EVENTS.MESSAGE_READ, (payload) => {\n callbacks.onMessageRead!(\n snakeToCamel<{ messageId: string; userId: string }>(payload)\n );\n });\n }\n if (callbacks.onMessagePinned) {\n bind<unknown>(EVENTS.MESSAGE_PINNED, (payload) => {\n callbacks.onMessagePinned!(snakeToCamel<Message>(payload));\n });\n }\n if (callbacks.onMessageUnpinned) {\n bind<unknown>(EVENTS.MESSAGE_UNPINNED, (payload) => {\n callbacks.onMessageUnpinned!(snakeToCamel<{ messageId: string }>(payload));\n });\n }\n\n // Presence is a single object per channel β€” first caller with an\n // `onPresence` callback wires it. Multi-presence consumers aren't a\n // real use case today; revisit if a second one shows up.\n if (callbacks.onPresence && !entry.presence) {\n const presence = new Presence(channel);\n presence.onSync(() => {\n const online: Record<string, { userId: string; isOnline: boolean }> = {};\n presence.list((id: string) => {\n online[id] = { userId: id, isOnline: true };\n });\n callbacks.onPresence!(online);\n });\n entry.presence = presence;\n this.presences.set(conversationId, presence);\n }\n\n entry.subscribers += 1;\n\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n\n const current = this.channels.get(conversationId);\n if (!current) return;\n\n for (const { event, ref } of refs) {\n current.channel.off(event, ref);\n }\n\n current.subscribers -= 1;\n if (current.subscribers <= 0) {\n current.channel.leave();\n this.channels.delete(conversationId);\n this.presences.delete(conversationId);\n }\n };\n\n return { channel, release };\n }\n\n /**\n * @deprecated Use the `release()` method returned by `joinConversation()`.\n * Kept as a no-op so older callers don't throw β€” but it cannot identify\n * which subscriber should leave, so it silently does nothing. Any code\n * still calling this will leak listeners and prevent the channel from\n * ever being torn down. Migrate to the subscription handle.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n leaveConversation(_conversationId: string): void {\n // intentional no-op β€” see ChannelSubscription.release on joinConversation()\n }\n\n /**\n * Look up the underlying Phoenix Channel for a conversation, if any\n * subscriber is still holding it. All send/push paths go through this\n * helper so the refcounted entry shape is contained to joinConversation.\n */\n private getChannel(conversationId: string): Channel | null {\n return this.channels.get(conversationId)?.channel ?? null;\n }\n\n /** Send a message to a conversation.\n *\n * Phoenix buffers pushes fired while a channel is still joining and\n * replays them on successful join. The default per-push timeout is 10s,\n * which is tight on slow dev backends β€” we bump to 30s so a late join\n * doesn't surface as a \"timed out\" error to a message that ultimately\n * persists. The caller still gets 'ok' once the server acks.\n */\n sendMessage(conversationId: string, payload: SendMessagePayload): Promise<Message> {\n return new Promise((resolve, reject) => {\n const channel = this.getChannel(conversationId);\n if (!channel) {\n reject({ code: 'NOT_JOINED', message: 'Not joined to this conversation' });\n return;\n }\n\n // If the underlying socket is down (token cleared, server restarted\n // mid-session, etc.) Phoenix will silently buffer the push until the\n // per-push timeout fires 30s later. Fail fast instead β€” the caller\n // can remove the optimistic row and the user can retry once we're\n // back online.\n if (!this.socket?.isConnected()) {\n reject({\n code: 'SOCKET_DISCONNECTED',\n message: 'Cannot send β€” chat server not connected',\n });\n return;\n }\n\n channel\n .push(EVENTS.MESSAGE_NEW, payload, 30_000)\n .receive('ok', (response: Message) => resolve(response))\n .receive('error', (reason: unknown) =>\n reject({ code: 'SEND_ERROR', message: 'Failed to send message', details: reason })\n )\n .receive('timeout', () =>\n reject({ code: 'TIMEOUT', message: 'Message send timed out' })\n );\n });\n }\n\n /** Broadcast typing indicator */\n sendTyping(conversationId: string, isTyping: boolean): void {\n const channel = this.getChannel(conversationId);\n channel?.push(EVENTS.USER_TYPING, {\n userId: this.config?.userId,\n userName: this.config?.userName,\n isTyping,\n });\n }\n\n /** Mark messages as read */\n markAsRead(conversationId: string, messageId: string): void {\n const channel = this.getChannel(conversationId);\n channel?.push(EVENTS.MESSAGE_READ, {\n messageId,\n userId: this.config?.userId,\n });\n }\n\n // ── Channel Management ──\n\n /** Add a user to the conversation */\n inviteUser(conversationId: string, payload: InviteUserPayload): Promise<Participant> {\n return this.channelPush(conversationId, 'invite_user', payload);\n }\n\n /** Remove a user from the conversation */\n removeUser(conversationId: string, userId: string): Promise<void> {\n return this.channelPush(conversationId, 'remove_user', { userId });\n }\n\n /** Update channel name/picture */\n updateChannel(conversationId: string, payload: ChannelUpdatePayload): Promise<Conversation> {\n return this.channelPush(conversationId, 'update_channel', payload);\n }\n\n /** Delete channel (admin only) */\n deleteChannel(conversationId: string): Promise<void> {\n return this.channelPush(conversationId, 'delete_channel', {});\n }\n\n /** Pin a message in the conversation (max MAX_PINNED_MESSAGES) */\n pinMessage(conversationId: string, messageId: string): Promise<Message> {\n return this.channelPush(conversationId, 'pin_message', { messageId });\n }\n\n /** Unpin a message in the conversation */\n unpinMessage(conversationId: string, messageId: string): Promise<void> {\n return this.channelPush(conversationId, 'unpin_message', { messageId });\n }\n\n /** Generic push with promise wrapper */\n private channelPush<T>(conversationId: string, event: string, payload: object): Promise<T> {\n return new Promise((resolve, reject) => {\n const channel = this.getChannel(conversationId);\n if (!channel) {\n reject({ code: 'NOT_JOINED', message: 'Not joined to this conversation' });\n return;\n }\n\n channel\n .push(event, payload)\n .receive('ok', (response: T) => resolve(response))\n .receive('error', (reason: unknown) =>\n reject({ code: 'CHANNEL_ERROR', message: `Failed: ${event}`, details: reason })\n );\n });\n }\n\n /** Check if connected */\n isConnected(): boolean {\n return this.socket?.isConnected() ?? false;\n }\n\n /** Disconnect socket and leave all channels */\n disconnect(): void {\n this.channels.forEach((entry) => entry.channel.leave());\n this.channels.clear();\n this.presences.clear();\n this.userChannel?.leave();\n this.socket?.disconnect();\n this.socket = null;\n this.config = null;\n }\n}\n","/**\n * Design tokens β€” the single source of truth for every visual value used\n * by the package. Components import from here instead of hard-coding pixel\n * values, so the scale stays coherent and a future theming pass can swap\n * these for CSS variables without touching every component.\n *\n * Conventions:\n * - Font sizes: modular scale (~1.18 ratio), nothing under 12px. Older\n * users at 100% zoom can still read everything that carries meaning.\n * - Spacing: 4px baseline grid (S1=4, S2=8, … S12=48). Combine, don't add\n * ad-hoc values.\n * - Radii: named buckets (\"md\" for buttons/cards, \"lg\" for bubbles).\n * - Colors: brand + neutral grayscale + a small semantic set. No more\n * hex literals in component files.\n */\n\n// ── Typography ─────────────────────────────────────────────────────────────\n\nexport const FONT_SIZE = {\n xs: '12px',\n sm: '13px',\n md: '15px',\n lg: '17px',\n xl: '20px',\n xxl: '28px',\n} as const;\n\nexport const FONT_WEIGHT = {\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n} as const;\n\nexport const LINE_HEIGHT = {\n tight: 1.3,\n normal: 1.45,\n loose: 1.6,\n} as const;\n\n// ── Spacing ────────────────────────────────────────────────────────────────\n// 4px baseline. Use S1..S12; if you want 6px or 10px you almost certainly\n// want S1 or S2 instead.\n\nexport const SPACE = {\n S1: '4px',\n S2: '8px',\n S3: '12px',\n S4: '16px',\n S5: '20px',\n S6: '24px',\n S8: '32px',\n S10: '40px',\n S12: '48px',\n} as const;\n\n// ── Radii ──────────────────────────────────────────────────────────────────\n\nexport const RADIUS = {\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n pill: '9999px',\n full: '50%',\n} as const;\n\n// ── Colors ─────────────────────────────────────────────────────────────────\n//\n// The brand + semantic colors are emitted as CSS variables by\n// ensureGlobalStyles() in core/styles.ts, with the hex literals below as\n// defaults. Host apps override individual variables via\n// CollabConfig.theme β€” components don't need to know whether they're\n// rendering the default or an override since they consume these tokens\n// either way.\n//\n// Neutrals and slate are kept as hex literals because changing them\n// wholesale breaks the package's tonal balance β€” those aren't part of\n// the theming surface.\n\n/** CSS variable names for the themeable color tokens. */\nexport const THEME_VAR = {\n primary: '--natoe-colab-primary',\n primaryHover: '--natoe-colab-primary-hover',\n primaryBg: '--natoe-colab-primary-bg',\n primaryFg: '--natoe-colab-primary-fg',\n success: '--natoe-colab-success',\n warning: '--natoe-colab-warning',\n danger: '--natoe-colab-danger',\n dangerBg: '--natoe-colab-danger-bg',\n dangerBorder: '--natoe-colab-danger-border',\n dangerFg: '--natoe-colab-danger-fg',\n fontStack: '--natoe-colab-font-stack',\n // Neutral surface palette β€” promoted to CSS vars so consumers (e.g.\n // CollabPanel themeMode='dark') can flip the whole grayscale at a subtree\n // level without re-themeing every component.\n white: '--natoe-colab-white',\n neutral50: '--natoe-colab-neutral-50',\n neutral100: '--natoe-colab-neutral-100',\n neutral200: '--natoe-colab-neutral-200',\n neutral300: '--natoe-colab-neutral-300',\n neutral400: '--natoe-colab-neutral-400',\n neutral500: '--natoe-colab-neutral-500',\n neutral600: '--natoe-colab-neutral-600',\n neutral700: '--natoe-colab-neutral-700',\n neutral800: '--natoe-colab-neutral-800',\n neutral900: '--natoe-colab-neutral-900',\n} as const;\n\n/** Default values for the themeable tokens (used by both CSS emission and\n * the inline-style fallback inside `var(..., fallback)`). */\nexport const THEME_DEFAULTS = {\n primary: '#2563eb',\n primaryHover: '#1d4ed8',\n primaryBg: '#dbeafe',\n primaryFg: '#1d4ed8',\n success: '#059669',\n warning: '#d97706',\n danger: '#dc2626',\n dangerBg: '#fef2f2',\n dangerBorder: '#fecaca',\n dangerFg: '#b91c1c',\n fontStack:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n // Neutral grayscale β€” these defaults are the same hex literals the\n // package shipped with; they're now overridable per-subtree.\n white: '#ffffff',\n neutral50: '#f9fafb',\n neutral100: '#f3f4f6',\n neutral200: '#e5e7eb',\n neutral300: '#d1d5db',\n neutral400: '#9ca3af',\n neutral500: '#6b7280',\n neutral600: '#4b5563',\n neutral700: '#374151',\n neutral800: '#1f2937',\n neutral900: '#111827',\n} as const;\n\n/** Public override shape β€” passed via CollabConfig.theme. Every key is\n * optional; unspecified keys fall back to {@link THEME_DEFAULTS}. */\nexport type Theme = Partial<Record<keyof typeof THEME_DEFAULTS, string>>;\n\nconst cssVar = (name: string, fallback: string): string => `var(${name}, ${fallback})`;\n\nexport const COLOR = {\n // Brand β€” themeable\n primary: cssVar(THEME_VAR.primary, THEME_DEFAULTS.primary),\n primaryHover: cssVar(THEME_VAR.primaryHover, THEME_DEFAULTS.primaryHover),\n /** Tinted surface for chips/cards on brand-coloured states. */\n primaryBg: cssVar(THEME_VAR.primaryBg, THEME_DEFAULTS.primaryBg),\n primaryFg: cssVar(THEME_VAR.primaryFg, THEME_DEFAULTS.primaryFg),\n\n // Neutral grayscale β€” themeable via CSS variables. Light-mode defaults\n // taken from Tailwind's zinc-leaning slate to match the package's\n // existing tonal balance; a host can override the entire palette by\n // setting --natoe-colab-* values on any ancestor element (used by\n // CollabPanel themeMode='dark' for the viewer's left-panel surface).\n white: cssVar(THEME_VAR.white, THEME_DEFAULTS.white),\n neutral50: cssVar(THEME_VAR.neutral50, THEME_DEFAULTS.neutral50),\n neutral100: cssVar(THEME_VAR.neutral100, THEME_DEFAULTS.neutral100),\n neutral200: cssVar(THEME_VAR.neutral200, THEME_DEFAULTS.neutral200),\n neutral300: cssVar(THEME_VAR.neutral300, THEME_DEFAULTS.neutral300),\n neutral400: cssVar(THEME_VAR.neutral400, THEME_DEFAULTS.neutral400),\n neutral500: cssVar(THEME_VAR.neutral500, THEME_DEFAULTS.neutral500),\n neutral600: cssVar(THEME_VAR.neutral600, THEME_DEFAULTS.neutral600),\n neutral700: cssVar(THEME_VAR.neutral700, THEME_DEFAULTS.neutral700),\n neutral800: cssVar(THEME_VAR.neutral800, THEME_DEFAULTS.neutral800),\n neutral900: cssVar(THEME_VAR.neutral900, THEME_DEFAULTS.neutral900),\n\n // Slate (used by day dividers + dialog title bar) β€” not themeable.\n slate200: '#e2e8f0',\n slate500: '#64748b',\n slate700: '#334155',\n slate800: '#1e293b',\n\n // Semantic β€” themeable\n success: cssVar(THEME_VAR.success, THEME_DEFAULTS.success),\n warning: cssVar(THEME_VAR.warning, THEME_DEFAULTS.warning),\n danger: cssVar(THEME_VAR.danger, THEME_DEFAULTS.danger),\n dangerBg: cssVar(THEME_VAR.dangerBg, THEME_DEFAULTS.dangerBg),\n dangerBorder: cssVar(THEME_VAR.dangerBorder, THEME_DEFAULTS.dangerBorder),\n dangerFg: cssVar(THEME_VAR.dangerFg, THEME_DEFAULTS.dangerFg),\n} as const;\n\n// ── Sizes / hit targets ────────────────────────────────────────────────────\n// Centralised so any \"interactive\" element gets a consistent 40-44px tap area.\n\nexport const SIZE = {\n /** Default interactive height (text buttons, list rows). */\n control: '40px',\n /** Square icon-only buttons inside chrome (popup title, menu trigger). */\n controlIcon: '36px',\n /** Primary input controls (textarea send/attach). 44px = WCAG min. */\n controlPrimary: '44px',\n /** Avatar in the inbox row. */\n avatar: '40px',\n /** Unread dot. */\n dot: '10px',\n} as const;\n\n// ── Shadow / elevation ─────────────────────────────────────────────────────\n\nexport const SHADOW = {\n /** Cards / floating popovers (message-actions menu). */\n popover: '0 6px 18px rgba(0, 0, 0, 0.12)',\n /** Dialog (CollabPopup). */\n dialog: '0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)',\n /** Subtle separator shadow (sticky day divider, toast). */\n subtle: '0 1px 2px rgba(0, 0, 0, 0.04)',\n toast: '0 4px 12px rgba(0, 0, 0, 0.18)',\n} as const;\n\n// ── Z-index buckets ────────────────────────────────────────────────────────\n\nexport const Z_INDEX = {\n /** Sticky day divider β€” above bubbles, below interactive popovers. */\n sticky: 1,\n /** Toasts inside a panel. */\n toast: 20,\n /** Floating CollabPopup dialog. */\n dialog: 9999,\n /** Portaled message-actions menu β€” must sit above the dialog. */\n menu: 10000,\n} as const;\n","/**\n * Shared style tokens + the global stylesheet the package injects once per\n * page.\n *\n * Top-level wrappers (CollabPopup, CollabPanel, CollabInline, CollabInbox)\n * import {@link FONT_STACK} so every surface renders with the same font\n * stack, even when the package is mounted inside an iframe whose\n * surrounding document doesn't set one.\n *\n * Themeable tokens (brand + semantic colors + the font stack) are emitted\n * as CSS custom properties on `:root` so host apps can override them via\n * `CollabConfig.theme` (see {@link applyThemeOverrides}). Non-themeable\n * tokens (neutrals, slate, spacing, radius, sizes) live as inline values\n * in core/theme.ts and stay constant.\n *\n * The prefers-contrast / prefers-reduced-motion adjustments are emitted\n * inside the same stylesheet so they apply wherever a `natoe-colab-root`\n * wrapper is mounted.\n */\n\nimport { THEME_DEFAULTS, THEME_VAR, type Theme } from './theme';\n\n/** CSS variable reference for the font stack (with the canonical default). */\nexport const FONT_STACK = `var(${THEME_VAR.fontStack}, ${THEME_DEFAULTS.fontStack})`;\n\n/** Class applied to every top-level wrapper so global styles can scope to us. */\nexport const ROOT_CLASS = 'natoe-colab-root';\n\nconst GLOBAL_STYLE_ID = 'natoe-colab-global-styles';\n\n/** :root declarations for the themeable token defaults, joined into one rule. */\nconst ROOT_DEFAULTS_BLOCK = (Object.keys(THEME_DEFAULTS) as Array<keyof typeof THEME_DEFAULTS>)\n .map((key) => ` ${THEME_VAR[key]}: ${THEME_DEFAULTS[key]};`)\n .join('\\n');\n\nconst GLOBAL_CSS = `\n:root {\n${ROOT_DEFAULTS_BLOCK}\n}\n\n@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }\n\n@keyframes natoe-colab-message-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* High-contrast adjustments β€” older users on OS-level high-contrast mode\n get heavier borders and stronger text without losing the package look. */\n@media (prefers-contrast: more) {\n .${ROOT_CLASS} {\n color: #000000;\n }\n .${ROOT_CLASS} button {\n outline: 1px solid currentColor;\n }\n}\n\n/* Honour reduced-motion preferences by killing entry animations. */\n@media (prefers-reduced-motion: reduce) {\n .${ROOT_CLASS} [data-natoe-message-bubble] {\n animation: none !important;\n }\n}\n`;\n\n/**\n * Idempotently inject the package's shared CSS (custom properties +\n * keyframes + media queries). Safe to call from any component constructor β€”\n * repeat calls are a no-op.\n */\nexport function ensureGlobalStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById(GLOBAL_STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = GLOBAL_STYLE_ID;\n style.textContent = GLOBAL_CSS;\n document.head.appendChild(style);\n}\n\n/**\n * Apply a host-supplied theme by setting CSS custom properties on the\n * document root. Keys missing from `theme` have their previously-set\n * override cleared so toggling overrides back to undefined returns the\n * default β€” never leaves stale values behind.\n */\nexport function applyThemeOverrides(theme: Theme | undefined): void {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n (Object.keys(THEME_VAR) as Array<keyof typeof THEME_VAR>).forEach((key) => {\n const value = theme?.[key];\n if (value) {\n root.style.setProperty(THEME_VAR[key], value);\n } else {\n root.style.removeProperty(THEME_VAR[key]);\n }\n });\n}\n","import React, { createContext, useContext, useEffect, useRef, useState, useCallback } from 'react';\nimport { CollabSocket } from '../core/socket';\nimport type {\n CollabConfig,\n ConversationListItem,\n ConversationPreview,\n CreateConversationResponse,\n Message,\n PreviewBatchResponse,\n SendMessagePayload,\n} from '../core/types';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\nimport { snakeToCamel } from '../core/caseConvert';\nimport { applyThemeOverrides } from '../core/styles';\n\ninterface FetchMessagesOptions {\n before?: string;\n limit?: number;\n}\n\ninterface CreateConversationOptions {\n name: string;\n participantIds?: string[];\n}\n\ninterface CollabContextValue {\n socket: CollabSocket;\n config: CollabConfig;\n apiBaseUrl: string;\n totalUnread: number;\n /**\n * Per-conversation unread counts, keyed by conversation ID. Updated\n * live via the user_notifications channel's unread_update push, so\n * surfaces like a minimized-chat chip can reflect changes without\n * mounting their own useConversation.\n */\n unreadCounts: Record<string, number>;\n /** Batched preview lookup β€” coalesces calls within a microtask */\n requestPreview: (orderId: string) => Promise<ConversationPreview | null>;\n /** Invalidate a cached preview (e.g. when a new message arrives) */\n invalidatePreview: (orderId: string) => void;\n /** Fetch paginated message history */\n fetchMessages: (conversationId: string, options?: FetchMessagesOptions) => Promise<Message[]>;\n /** Atomic create-or-send β€” creates conversation if missing, then stores the first message */\n createConversationWithMessage: (\n orderId: string,\n message: SendMessagePayload,\n options: CreateConversationOptions\n ) => Promise<CreateConversationResponse>;\n /** Add a user to an existing conversation (e.g. when radiologist is assigned later) */\n addParticipant: (conversationId: string, userId: string) => Promise<void>;\n /** Remove a user from a conversation */\n removeParticipant: (conversationId: string, userId: string) => Promise<void>;\n /** Fetch the current user's full conversation list β€” feeds the CollabInbox sidebar */\n fetchConversationList: () => Promise<ConversationListItem[]>;\n /** Pin a message (max MAX_PINNED_MESSAGES per conversation β€” backend enforces) */\n pinMessage: (conversationId: string, messageId: string) => Promise<void>;\n /** Unpin a message */\n unpinMessage: (conversationId: string, messageId: string) => Promise<void>;\n /** Fetch current pinned messages for a conversation */\n fetchPinnedMessages: (conversationId: string) => Promise<Message[]>;\n}\n\nexport const CollabContext = createContext<CollabContextValue | null>(null);\nexport type { CollabContextValue };\n\nexport function useCollab(): CollabContextValue {\n const context = useContext(CollabContext);\n if (!context) {\n throw new Error('useCollab must be used within a <CollabProvider>');\n }\n return context;\n}\n\ninterface CollabProviderProps {\n config: CollabConfig;\n children: React.ReactNode;\n /** REST API base URL for the Phoenix backend (e.g. https://backend.natoe.ai) */\n apiBaseUrl: string;\n}\n\nexport function CollabProvider({ config, apiBaseUrl, children }: CollabProviderProps) {\n // Using useState (not useRef) so children re-render once the socket is ready.\n // Instantiated synchronously on first render so children have a non-null\n // socket reference immediately; the ACTUAL connect() happens in the\n // effect below, after the unread-count handler is wired in β€” otherwise\n // the backend's initial :after_join push races the handler registration\n // and the first unread_update is dropped silently.\n const [socket, setSocket] = useState<CollabSocket | null>(() => {\n if (typeof window === 'undefined') return null;\n return new CollabSocket();\n });\n const [unreadCounts, setUnreadCounts] = useState<Record<string, number>>({});\n\n // Preview batching state\n const pendingOrderIds = useRef<Set<string>>(new Set());\n const pendingResolvers = useRef<Map<string, Array<(preview: ConversationPreview | null) => void>>>(new Map());\n const previewCache = useRef<Map<string, ConversationPreview | null>>(new Map());\n const batchScheduled = useRef(false);\n\n // Apply host theme overrides to the document root as CSS custom\n // properties. Re-runs whenever the theme prop reference changes so a\n // host that rebuilds its config object (e.g. on locale/brand switch)\n // sees the new colors immediately. Keys absent from the new theme\n // object are explicitly cleared so toggling them back to undefined\n // restores the package defaults β€” no stale values.\n useEffect(() => {\n applyThemeOverrides(config.theme);\n }, [config.theme]);\n\n // Wire unread-count listener + reconnect when identity changes.\n // The socket instance (wrapper) is created lazily in useState above, but\n // the underlying Phoenix Socket is only created if getToken() returned\n // something at that first render. When the token arrives later (post-login),\n // this effect re-fires and asks the wrapper to connect for real.\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n // Create the wrapper if it wasn't created during the useState init\n // (e.g. SSR branch that short-circuited).\n let s = socket;\n if (!s) {\n s = new CollabSocket();\n setSocket(s);\n }\n\n // Register the unread handler BEFORE connect() so the backend's\n // :after_join push (initial counts, fires immediately on channel join)\n // is never dropped because the handler was still unset. Push-driven\n // updates also clear the preview cache so the next popup open fetches\n // fresh server truth.\n s.onUnreadCountUpdate((counts) => {\n setUnreadCounts(counts);\n previewCache.current.clear();\n });\n\n // connect() is idempotent β€” no-op when already connected, retries when\n // the prior init saw an empty token.\n if (!s.isConnected()) {\n s.connect(config);\n }\n\n // Intentionally no cleanup disconnect here β€” identity changes should\n // reconnect in place rather than tearing down the whole session.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [config.socketUrl, config.userId]);\n\n const authHeaders = useCallback(\n (): HeadersInit => ({\n Authorization: `Bearer ${config.getToken()}`,\n 'Content-Type': 'application/json',\n }),\n [config]\n );\n\n // ── Batch preview fetching ──────────────────────────────────────────\n\n const flushPreviewBatch = useCallback(async () => {\n const orderIds = Array.from(pendingOrderIds.current);\n const resolvers = new Map(pendingResolvers.current);\n pendingOrderIds.current.clear();\n pendingResolvers.current.clear();\n batchScheduled.current = false;\n\n if (orderIds.length === 0) return;\n\n try {\n const query = orderIds.map((id) => `order_ids[]=${encodeURIComponent(id)}`).join('&');\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/conversations/previews?${query}`, {\n headers: authHeaders(),\n });\n\n if (!response.ok) throw new Error(`Preview batch failed: ${response.status}`);\n\n const data: PreviewBatchResponse = snakeToCamel(await response.json());\n\n orderIds.forEach((orderId) => {\n const preview = data.previews[orderId] ?? null;\n if (preview !== null) {\n previewCache.current.set(orderId, preview);\n }\n resolvers.get(orderId)?.forEach((resolve) => resolve(preview));\n });\n } catch (error) {\n config.onError?.({\n code: 'PREVIEW_BATCH_ERROR',\n message: 'Failed to fetch conversation previews',\n details: error,\n });\n orderIds.forEach((orderId) => {\n resolvers.get(orderId)?.forEach((resolve) => resolve(null));\n });\n }\n }, [apiBaseUrl, authHeaders, config]);\n\n const requestPreview = useCallback(\n (orderId: string): Promise<ConversationPreview | null> => {\n // Return cached if available\n if (previewCache.current.has(orderId)) {\n return Promise.resolve(previewCache.current.get(orderId) ?? null);\n }\n\n return new Promise((resolve) => {\n pendingOrderIds.current.add(orderId);\n const existing = pendingResolvers.current.get(orderId) || [];\n existing.push(resolve);\n pendingResolvers.current.set(orderId, existing);\n\n if (!batchScheduled.current) {\n batchScheduled.current = true;\n queueMicrotask(flushPreviewBatch);\n }\n });\n },\n [flushPreviewBatch]\n );\n\n const invalidatePreview = useCallback((orderId: string) => {\n previewCache.current.delete(orderId);\n }, []);\n\n // ── Message history ──────────────────────────────────────────\n\n const fetchMessages = useCallback(\n async (conversationId: string, options: FetchMessagesOptions = {}): Promise<Message[]> => {\n const limit = options.limit ?? MESSAGES_PAGE_SIZE;\n const params = new URLSearchParams({ limit: String(limit) });\n if (options.before) params.set('before', options.before);\n\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages?${params.toString()}`,\n { headers: authHeaders() }\n );\n\n if (!response.ok) {\n throw { code: 'FETCH_ERROR', message: 'Failed to fetch messages', status: response.status };\n }\n\n const msgs: Message[] = snakeToCamel(await response.json());\n return msgs.sort((a, b) => a.insertedAt.localeCompare(b.insertedAt));\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Atomic create-or-send ──────────────────────────────────────────\n\n const createConversationWithMessage = useCallback(\n async (\n orderId: string,\n message: SendMessagePayload,\n options: CreateConversationOptions\n ): Promise<CreateConversationResponse> => {\n if (!orderId || !orderId.trim()) {\n throw {\n code: 'INVALID_ORDER_ID',\n message:\n 'Cannot create conversation: orderId is empty. Host app passed an order with no orderId/mainOrderId set.',\n };\n }\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/orders/${orderId}/messages`, {\n method: 'POST',\n headers: authHeaders(),\n body: JSON.stringify({\n message,\n conversation: {\n name: options.name,\n participant_ids: options.participantIds ?? [],\n },\n }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw { code: 'CREATE_ERROR', message: 'Failed to create conversation', details: error };\n }\n\n const data: CreateConversationResponse = snakeToCamel(await response.json());\n\n // The backend may have appended this message to an EXISTING\n // study-scoped conversation that already has plenty of history.\n // Drop the cached preview so the next requestPreview fetches truth\n // instead of reading a stale snapshot from before the new message.\n previewCache.current.delete(orderId);\n\n return data;\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Participant management ──────────────────────────────────────────\n\n const addParticipant = useCallback(\n async (conversationId: string, userId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/participants`,\n {\n method: 'POST',\n headers: authHeaders(),\n body: JSON.stringify({ user_id: userId }),\n }\n );\n\n if (!response.ok) {\n throw { code: 'ADD_PARTICIPANT_ERROR', message: 'Failed to add participant' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const removeParticipant = useCallback(\n async (conversationId: string, userId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/participants/${userId}`,\n {\n method: 'DELETE',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n throw { code: 'REMOVE_PARTICIPANT_ERROR', message: 'Failed to remove participant' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n // ── Conversation list (Inbox) ──────────────────────────────────────────\n\n const fetchConversationList = useCallback(async (): Promise<ConversationListItem[]> => {\n const response = await fetch(`${apiBaseUrl}/api/natoe-colab/conversations`, {\n headers: authHeaders(),\n });\n\n if (!response.ok) {\n throw { code: 'LIST_ERROR', message: 'Failed to fetch conversation list' };\n }\n\n return snakeToCamel(await response.json());\n }, [apiBaseUrl, authHeaders]);\n\n // ── Pin management ──────────────────────────────────────────\n\n const pinMessage = useCallback(\n async (conversationId: string, messageId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages/${messageId}/pin`,\n {\n method: 'POST',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw { code: 'PIN_ERROR', message: 'Failed to pin message', details: error };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const unpinMessage = useCallback(\n async (conversationId: string, messageId: string): Promise<void> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/messages/${messageId}/pin`,\n {\n method: 'DELETE',\n headers: authHeaders(),\n }\n );\n\n if (!response.ok) {\n throw { code: 'UNPIN_ERROR', message: 'Failed to unpin message' };\n }\n },\n [apiBaseUrl, authHeaders]\n );\n\n const fetchPinnedMessages = useCallback(\n async (conversationId: string): Promise<Message[]> => {\n const response = await fetch(\n `${apiBaseUrl}/api/natoe-colab/conversations/${conversationId}/pinned`,\n { headers: authHeaders() }\n );\n\n if (!response.ok) {\n throw { code: 'FETCH_PINNED_ERROR', message: 'Failed to fetch pinned messages' };\n }\n\n return snakeToCamel(await response.json());\n },\n [apiBaseUrl, authHeaders]\n );\n\n const totalUnread = Object.values(unreadCounts).reduce((sum, count) => sum + count, 0);\n\n if (!socket) return null;\n\n return (\n <CollabContext.Provider\n value={{\n socket,\n config,\n apiBaseUrl,\n totalUnread,\n unreadCounts,\n requestPreview,\n invalidatePreview,\n fetchMessages,\n createConversationWithMessage,\n addParticipant,\n removeParticipant,\n fetchConversationList,\n pinMessage,\n unpinMessage,\n fetchPinnedMessages,\n }}\n >\n {children}\n </CollabContext.Provider>\n );\n}\n","import type { PatientData } from './types';\n\n/**\n * Canonical channel name format, used both when creating conversations\n * and wherever a channel needs to be labeled in the UI.\n *\n * Format: `<patient> - <lab> - <last 4 of order id>`\n * Example: \"John Doe - Beachside Lab - 1189\"\n *\n * If `labName` is missing (host order didn't carry lab info) the lab\n * segment is dropped instead of rendered as an empty `\" - - \"`. The\n * `cleanChannelName` helper applies the same collapse to strings that\n * arrived from the server (older conversations may have been persisted\n * with the empty segment baked in).\n */\nexport function buildChannelName(patientData: PatientData): string {\n const patientPart = patientData.patientName?.trim() || 'Unknown';\n const labPart = patientData.labName?.trim()?.slice(0, 24) || '';\n const last4 = (patientData.displayOrderId ?? '').trim().slice(-4) || '0000';\n return labPart\n ? `${patientPart} - ${labPart} - ${last4}`\n : `${patientPart} - ${last4}`;\n}\n\n/**\n * Collapse the empty-lab segment from a server-stored channel name.\n *\n * Pre-fix, the package would persist `conversation.name` as\n * `\"Patient - - 1234\"` whenever the host omitted labName. Those records\n * still exist in the DB. Run server-supplied names through here before\n * rendering so the empty middle segment doesn't leak into the UI.\n */\nexport function cleanChannelName(name: string | undefined | null): string {\n if (!name) return '';\n // Collapse \"<x> - - <y>\" (any whitespace between the two dashes) to\n // \"<x> - <y>\". Tolerates both single and double-space middles.\n return name.replace(/\\s+-\\s+-\\s+/g, ' - ').trim();\n}\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n Message,\n Participant,\n Conversation,\n SendMessagePayload,\n TypingEvent,\n PatientData,\n} from '../core/types';\nimport { buildChannelName } from '../core/channelName';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\n\ninterface UseConversationOptions {\n orderId: string;\n patientData: PatientData;\n /** Participant user IDs used only when creating a brand-new conversation */\n participantIds?: string[];\n /** Load full history on mount (default true) */\n loadHistory?: boolean;\n}\n\ninterface UseConversationReturn {\n conversation: Conversation | null;\n messages: Message[];\n pinnedMessages: Message[];\n participants: Participant[];\n typingUsers: TypingEvent[];\n isLoading: boolean;\n hasMore: boolean;\n error: string | null;\n isConnected: boolean;\n /** Message currently being replied to (null if not replying) */\n replyTo: Message | null;\n /** Set/clear the active reply target */\n setReplyTo: (message: Message | null) => void;\n sendMessage: (body: string) => Promise<void>;\n /** Re-attempt sending a previously-failed optimistic text message */\n retryMessage: (messageId: string) => Promise<void>;\n sendAudioMessage: (audioBlob: Blob, duration: number) => Promise<void>;\n sendFileMessage: (file: File) => Promise<void>;\n sendDeepLink: (path: string, label: string) => Promise<void>;\n sendTyping: (isTyping: boolean) => void;\n markAsRead: (messageId: string) => void;\n loadMoreMessages: () => Promise<void>;\n pinMessage: (messageId: string) => Promise<void>;\n unpinMessage: (messageId: string) => Promise<void>;\n}\n\n/**\n * Full conversation hook used by CollabPanel / CollabPopup.\n *\n * Lazy creation: the conversation is NOT created on mount. It's only created\n * when the user sends the first message. If a conversation already exists for\n * the given orderId, it's loaded and joined automatically.\n */\nexport function useConversation({\n orderId,\n patientData,\n participantIds = [],\n loadHistory = true,\n}: UseConversationOptions): UseConversationReturn {\n const {\n socket,\n config,\n requestPreview,\n invalidatePreview,\n fetchMessages,\n createConversationWithMessage,\n pinMessage: pinMessageApi,\n unpinMessage: unpinMessageApi,\n } = useCollab();\n\n const [conversation, setConversation] = useState<Conversation | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const [pinnedMessages, setPinnedMessages] = useState<Message[]>([]);\n const [participants, setParticipants] = useState<Participant[]>([]);\n const [typingUsers, setTypingUsers] = useState<TypingEvent[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [replyTo, setReplyTo] = useState<Message | null>(null);\n\n const joinedConversationId = useRef<string | null>(null);\n // Holds the per-subscriber release function returned by socket.joinConversation.\n // Calling release() unbinds only this hook's listeners; the underlying channel\n // stays alive while sibling subscribers (e.g. an inline preview rendered next\n // to this panel) are still holding it.\n const channelSubscription = useRef<{ release: () => void } | null>(null);\n const typingTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n // In-flight promise for the lazy-create call. Two sends hitting before\n // state updates would each see `conversation: null` and POST twice; with\n // this guard, the second caller awaits the first's result instead.\n const ensureConversationInFlight = useRef<Promise<Conversation> | null>(null);\n // Messages we've already sent a `message:read` push for, in this session.\n // The MessageList's IntersectionObserver refires on every messages[] state\n // change; without this dedupe, every broadcast-driven readBy update\n // retriggers mark-read on every visible row, causing a runaway loop.\n const markedReadIdsRef = useRef<Set<string>>(new Set());\n\n // Build the canonical channel name at create time. If the host's\n // patientData doesn't carry a labName AND the current user is a lab,\n // fall back to their userName β€” that's the common \"lab user starts a\n // chat on their own order\" path, and without this fallback the\n // conversation gets persisted server-side with an empty lab segment.\n const buildName = useCallback(\n (): string => {\n const labName =\n patientData.labName ??\n (config.userRole === 'lab' ? config.userName : undefined);\n return buildChannelName({ ...patientData, labName });\n },\n [patientData, config.userRole, config.userName]\n );\n\n const joinChannel = useCallback(\n (conv: Conversation) => {\n if (joinedConversationId.current === conv.id) return;\n\n // Release any prior subscription before binding a new one (avoids\n // stacking listeners on case-switch within the same mount).\n channelSubscription.current?.release();\n channelSubscription.current = null;\n\n const subscription = socket.joinConversation(conv.id, {\n // Dedupe by id so an optimistic message (added client-side on send)\n // doesn't double up when the server's broadcast arrives.\n onMessage: (msg) =>\n setMessages((prev) => {\n if (prev.some((m) => m.id === msg.id)) return prev;\n // Replace any optimistic twin (same sender, same body, still pending).\n const optimisticIdx = prev.findIndex(\n (m) =>\n m.id.startsWith('pending-') &&\n m.senderId === msg.senderId &&\n m.body === msg.body\n );\n if (optimisticIdx >= 0) {\n const next = prev.slice();\n next[optimisticIdx] = msg;\n return next;\n }\n return [...prev, msg];\n }),\n onTyping: (event) => {\n if (event.userId === config.userId) return;\n\n if (event.isTyping) {\n setTypingUsers((prev) => {\n const exists = prev.some((t) => t.userId === event.userId);\n return exists ? prev : [...prev, event];\n });\n const existingTimer = typingTimers.current.get(event.userId);\n if (existingTimer) clearTimeout(existingTimer);\n const timer = setTimeout(() => {\n setTypingUsers((prev) => prev.filter((t) => t.userId !== event.userId));\n typingTimers.current.delete(event.userId);\n }, 3000);\n typingTimers.current.set(event.userId, timer);\n } else {\n setTypingUsers((prev) => prev.filter((t) => t.userId !== event.userId));\n const timer = typingTimers.current.get(event.userId);\n if (timer) clearTimeout(timer);\n typingTimers.current.delete(event.userId);\n }\n },\n onUserJoined: (participant) => {\n setParticipants((prev) =>\n prev.some((p) => p.userId === participant.userId) ? prev : [...prev, participant]\n );\n },\n onUserLeft: (participant) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== participant.userId));\n },\n onChannelUpdated: (updates) => {\n setConversation((prev) => (prev ? { ...prev, ...updates } : prev));\n },\n onChannelDeleted: () => {\n setConversation(null);\n setMessages([]);\n channelSubscription.current?.release();\n channelSubscription.current = null;\n joinedConversationId.current = null;\n setIsConnected(false);\n },\n onMessageRead: ({ messageId, userId }) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === messageId && !(msg.readBy ?? []).includes(userId)\n ? { ...msg, readBy: [...(msg.readBy ?? []), userId] }\n : msg\n )\n );\n },\n onMessagePinned: (message) => {\n setPinnedMessages((prev) =>\n prev.some((m) => m.id === message.id) ? prev : [...prev, message]\n );\n setMessages((prev) =>\n prev.map((m) => (m.id === message.id ? { ...m, isPinned: true } : m))\n );\n },\n onMessageUnpinned: ({ messageId }) => {\n setPinnedMessages((prev) => prev.filter((m) => m.id !== messageId));\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, isPinned: false } : m))\n );\n },\n });\n\n channelSubscription.current = subscription;\n joinedConversationId.current = conv.id;\n setIsConnected(true);\n },\n [socket, config.userId]\n );\n\n // Initial load: check for existing conversation via preview\n useEffect(() => {\n let cancelled = false;\n\n const init = async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const preview = await requestPreview(orderId);\n\n if (cancelled) return;\n\n if (!preview) {\n // No conversation exists yet β€” stay in \"new\" mode\n setConversation(null);\n setMessages([]);\n setParticipants([]);\n setHasMore(false);\n setIsLoading(false);\n return;\n }\n\n const existingConv: Conversation = {\n id: preview.conversationId,\n orderId: preview.orderId,\n name: preview.name,\n participants: preview.participants,\n unreadCount: preview.unreadCount,\n createdAt: '',\n updatedAt: '',\n };\n\n setConversation(existingConv);\n setParticipants(preview.participants);\n // Channel join kicks off synchronously (Phoenix push handles the\n // async part). Renders can proceed while the join completes.\n joinChannel(existingConv);\n\n // Skip preview.lastMessages as the initial paint β€” that two-wave\n // pattern (preview β†’ history merge) was prepending older messages\n // after MessageList had already done its initial scroll, stranding\n // the user mid-thread. Wait for fetchMessages so we paint once,\n // with the full first page, and the scroll lands correctly on the\n // first try. The preview is still used above for conversation\n // metadata (id, name, participants) and over in the inbox row's\n // last-message blurb β€” just not as the initial message list state\n // here.\n if (loadHistory) {\n fetchMessages(preview.conversationId)\n .then((history) => {\n if (cancelled) return;\n setMessages(history);\n setHasMore(history.length >= MESSAGES_PAGE_SIZE);\n setPinnedMessages(history.filter((m) => m.isPinned));\n setIsLoading(false);\n })\n .catch(() => {\n if (cancelled) return;\n // fetchMessages surfaces the error via onError. Drop the\n // loading state so the panel doesn't hang on a stuck spinner;\n // the user can still send a new message (which doesn't\n // depend on the historical fetch).\n setIsLoading(false);\n });\n } else {\n // Caller explicitly opted out of history; paint empty and let\n // socket-driven new messages stream in.\n setMessages([]);\n setHasMore(false);\n setPinnedMessages([]);\n setIsLoading(false);\n }\n } catch (err) {\n if (cancelled) return;\n const msg = err instanceof Error ? err.message : 'Failed to load conversation';\n setError(msg);\n setIsLoading(false);\n }\n };\n\n init();\n\n return () => {\n cancelled = true;\n // Release this hook's subscription only β€” the channel stays alive\n // for sibling subscribers (inline preview + expanded panel often\n // coexist on the same conversation).\n channelSubscription.current?.release();\n channelSubscription.current = null;\n joinedConversationId.current = null;\n typingTimers.current.forEach((timer) => clearTimeout(timer));\n typingTimers.current.clear();\n markedReadIdsRef.current.clear();\n setIsConnected(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [orderId]);\n\n // ── Send helpers ──\n\n // `persistedByCreate` tells the caller whether THEIR payload was written\n // by the REST create (true = don't also send via socket, that would dup).\n // - conversation already existed β†’ false\n // - piggy-backed on someone else's in-flight create β†’ false (their payload\n // needs a socket send)\n // - this caller kicked off the create β†’ true (their payload was in the POST)\n const ensureConversation = useCallback(\n async (\n payload: SendMessagePayload\n ): Promise<{ conv: Conversation; persistedByCreate: boolean }> => {\n if (conversation) return { conv: conversation, persistedByCreate: false };\n\n if (ensureConversationInFlight.current) {\n const conv = await ensureConversationInFlight.current;\n return { conv, persistedByCreate: false };\n }\n\n const inflight = (async () => {\n const result = await createConversationWithMessage(orderId, payload, {\n name: buildName(),\n participantIds,\n });\n\n setConversation(result.conversation);\n setParticipants(result.conversation.participants);\n setMessages([result.message]);\n joinChannel(result.conversation);\n invalidatePreview(orderId);\n\n // Create-or-send may have appended our message to an EXISTING\n // study-scoped conversation with prior history β€” the init effect's\n // preview-backed load doesn't cover that case because `conversation`\n // was null when it ran. Pull authoritative history now and merge\n // (dedupe by id so the just-inserted message isn't duplicated).\n if (loadHistory) {\n fetchMessages(result.conversation.id)\n .then((history) => {\n setMessages((prev) => {\n const seen = new Set(prev.map((m) => m.id));\n const older = history.filter((m) => !seen.has(m.id));\n return [...older, ...prev];\n });\n setPinnedMessages((prev) => {\n const fromHistory = history.filter((m) => m.isPinned);\n const seen = new Set(prev.map((m) => m.id));\n return [...fromHistory.filter((m) => !seen.has(m.id)), ...prev];\n });\n })\n .catch(() => {\n // Non-fatal β€” fetchMessages already surfaces via onError.\n });\n }\n\n return result.conversation;\n })();\n\n ensureConversationInFlight.current = inflight;\n\n try {\n const conv = await inflight;\n return { conv, persistedByCreate: true };\n } finally {\n ensureConversationInFlight.current = null;\n }\n },\n [\n conversation,\n createConversationWithMessage,\n orderId,\n buildName,\n participantIds,\n joinChannel,\n invalidatePreview,\n loadHistory,\n fetchMessages,\n ]\n );\n\n const sendMessage = useCallback(\n async (body: string) => {\n const payload: SendMessagePayload = {\n body,\n type: 'text',\n ...(replyTo ? { reply_to_id: replyTo.id } : {}),\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n setReplyTo(null);\n\n // Our message was already written by the REST create β€” skip the socket\n // push, otherwise we'd persist the same message twice.\n if (persistedByCreate) return;\n\n // Optimistic insert so the user sees their text instantly, regardless\n // of socket roundtrip. The server broadcast (via onMessage above) will\n // swap this in for the real, persisted message.\n const optimistic: Message = {\n id: `pending-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n conversationId: conv.id,\n senderId: config.userId,\n senderName: config.userName,\n senderRole: config.userRole,\n body,\n type: 'text',\n insertedAt: new Date().toISOString(),\n status: 'sending',\n ...(replyTo\n ? {\n replyToId: replyTo.id,\n replyToSnapshot: {\n messageId: replyTo.id,\n senderId: replyTo.senderId,\n senderName: replyTo.senderName,\n body: replyTo.body,\n type: replyTo.type,\n },\n }\n : {}),\n };\n setMessages((prev) => [...prev, optimistic]);\n\n try {\n await socket.sendMessage(conv.id, payload);\n } catch (err) {\n // Keep the bubble in place but flip its status so the user sees\n // \"Failed\" + a Retry affordance instead of the message silently\n // vanishing. If the server actually persisted and broadcasts the\n // same message later, the onMessage twin-match below will swap\n // this row out naturally.\n setMessages((prev) =>\n prev.map((m) => (m.id === optimistic.id ? { ...m, status: 'failed' as const } : m))\n );\n config.onError?.({\n code: 'SEND_FAILED',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [ensureConversation, socket, replyTo, config]\n );\n\n const retryMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n const target = messages.find((m) => m.id === messageId);\n if (!target || target.status !== 'failed' || target.type !== 'text') return;\n\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, status: 'sending' as const } : m))\n );\n\n const payload: SendMessagePayload = {\n body: target.body,\n type: 'text',\n ...(target.replyToId ? { reply_to_id: target.replyToId } : {}),\n };\n\n try {\n await socket.sendMessage(conversation.id, payload);\n } catch (err) {\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? { ...m, status: 'failed' as const } : m))\n );\n config.onError?.({\n code: 'SEND_FAILED',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [conversation, messages, socket, config]\n );\n\n const sendAudioMessage = useCallback(\n async (audioBlob: Blob, duration: number) => {\n if (!config.onUploadFile) return;\n const url = await config.onUploadFile(audioBlob, 'voice-message.webm');\n const payload: SendMessagePayload = {\n body: 'Voice message',\n type: 'audio',\n media_url: url,\n media_duration: duration,\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [config, ensureConversation, socket]\n );\n\n const sendFileMessage = useCallback(\n async (file: File) => {\n if (!config.onUploadFile) return;\n const url = await config.onUploadFile(file, file.name);\n const isImage = file.type.startsWith('image/');\n const payload: SendMessagePayload = {\n body: file.name,\n type: isImage ? 'image' : 'file',\n media_url: url,\n file_name: file.name,\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [config, ensureConversation, socket]\n );\n\n const sendDeepLink = useCallback(\n async (path: string, label: string) => {\n const payload: SendMessagePayload = {\n body: label,\n type: 'deep_link',\n metadata: { path },\n };\n const { conv, persistedByCreate } = await ensureConversation(payload);\n if (persistedByCreate) return;\n await socket.sendMessage(conv.id, payload);\n },\n [ensureConversation, socket]\n );\n\n const sendTypingIndicator = useCallback(\n (isTyping: boolean) => {\n if (!conversation || !isConnected) return;\n socket.sendTyping(conversation.id, isTyping);\n },\n [conversation, isConnected, socket]\n );\n\n const markAsRead = useCallback(\n (messageId: string) => {\n if (!conversation || !isConnected) return;\n if (markedReadIdsRef.current.has(messageId)) return;\n markedReadIdsRef.current.add(messageId);\n socket.markAsRead(conversation.id, messageId);\n },\n [conversation, isConnected, socket]\n );\n\n const loadMoreMessages = useCallback(async () => {\n if (!conversation || !hasMore || isLoading) return;\n\n const oldestMessage = messages[0];\n const before = oldestMessage?.id;\n\n setIsLoading(true);\n try {\n const older = await fetchMessages(conversation.id, { before });\n setMessages((prev) => [...older, ...prev]);\n setHasMore(older.length > 0);\n } catch (err) {\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load older messages',\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [conversation, hasMore, isLoading, messages, fetchMessages, config]);\n\n const pinMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n try {\n await pinMessageApi(conversation.id, messageId);\n } catch (err) {\n config.onError?.({\n code: 'PIN_ERROR',\n message: 'Failed to pin message',\n details: err,\n });\n throw err;\n }\n },\n [conversation, pinMessageApi, config]\n );\n\n const unpinMessage = useCallback(\n async (messageId: string) => {\n if (!conversation) return;\n try {\n await unpinMessageApi(conversation.id, messageId);\n } catch (err) {\n config.onError?.({\n code: 'UNPIN_ERROR',\n message: 'Failed to unpin message',\n details: err,\n });\n throw err;\n }\n },\n [conversation, unpinMessageApi, config]\n );\n\n return {\n conversation,\n messages,\n pinnedMessages,\n participants,\n typingUsers,\n isLoading,\n hasMore,\n error,\n isConnected,\n replyTo,\n setReplyTo,\n sendMessage,\n retryMessage,\n sendAudioMessage,\n sendFileMessage,\n sendDeepLink,\n sendTyping: sendTypingIndicator,\n markAsRead,\n loadMoreMessages,\n pinMessage,\n unpinMessage,\n };\n}\n","import { useCallback, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n ChannelUpdatePayload,\n InviteUserPayload,\n CollabError,\n} from '../core/types';\n\ninterface UseChannelSettingsOptions {\n conversationId: string | null;\n}\n\ninterface UseChannelSettingsReturn {\n /** Invite a user to the conversation */\n inviteUser: (payload: InviteUserPayload) => Promise<void>;\n /** Remove a user from the conversation (admin/creator only) */\n removeUser: (userId: string) => Promise<void>;\n /** Current user leaves the conversation */\n leaveChannel: () => Promise<void>;\n /** Delete the conversation entirely (admin only) */\n deleteChannel: () => Promise<void>;\n /** Update channel name and/or picture */\n updateChannel: (payload: ChannelUpdatePayload) => Promise<void>;\n /** Whether an operation is in progress */\n isUpdating: boolean;\n /** Last error from any operation */\n error: CollabError | null;\n /** Whether current user can perform admin actions */\n isAdmin: boolean;\n}\n\nexport function useChannelSettings({ conversationId }: UseChannelSettingsOptions): UseChannelSettingsReturn {\n const { socket, config } = useCollab();\n const [isUpdating, setIsUpdating] = useState(false);\n const [error, setError] = useState<CollabError | null>(null);\n\n const isAdmin = config.userRole === 'admin';\n\n const withLoading = useCallback(\n async <T>(operation: () => Promise<T>): Promise<T | undefined> => {\n if (!conversationId) return;\n setIsUpdating(true);\n setError(null);\n try {\n const result = await operation();\n setIsUpdating(false);\n return result;\n } catch (err) {\n const collabError: CollabError =\n typeof err === 'object' && err !== null && 'code' in err\n ? (err as CollabError)\n : { code: 'UNKNOWN', message: 'Operation failed' };\n\n setError(collabError);\n setIsUpdating(false);\n config.onError?.(collabError);\n return undefined;\n }\n },\n [conversationId, config]\n );\n\n const inviteUser = useCallback(\n async (payload: InviteUserPayload) => {\n await withLoading(() => socket.inviteUser(conversationId!, payload));\n },\n [conversationId, socket, withLoading]\n );\n\n const removeUser = useCallback(\n async (userId: string) => {\n await withLoading(() => socket.removeUser(conversationId!, userId));\n },\n [conversationId, socket, withLoading]\n );\n\n const leaveChannel = useCallback(async () => {\n await withLoading(async () => {\n await socket.removeUser(conversationId!, config.userId);\n socket.leaveConversation(conversationId!);\n });\n }, [conversationId, socket, config.userId, withLoading]);\n\n const deleteChannel = useCallback(async () => {\n if (!isAdmin) {\n const err: CollabError = {\n code: 'FORBIDDEN',\n message: 'Only admins can delete channels',\n };\n setError(err);\n config.onError?.(err);\n return;\n }\n await withLoading(() => socket.deleteChannel(conversationId!));\n }, [conversationId, socket, isAdmin, config, withLoading]);\n\n const updateChannel = useCallback(\n async (payload: ChannelUpdatePayload) => {\n await withLoading(() => socket.updateChannel(conversationId!, payload));\n },\n [conversationId, socket, withLoading]\n );\n\n return {\n inviteUser,\n removeUser,\n leaveChannel,\n deleteChannel,\n updateChannel,\n isUpdating,\n error,\n isAdmin,\n };\n}\n","import { useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport { DEEP_LINK_PREFIX } from '../core/constants';\n\ninterface ParsedDeepLink {\n /** Full original link string */\n raw: string;\n /** The path after natoe:// (e.g. \"order/4521\") */\n path: string;\n /** The resource type (e.g. \"order\", \"report\", \"dicom\", \"study\") */\n resource: string;\n /** The resource ID */\n id: string;\n}\n\ninterface UseDeepLinksReturn {\n /** Parse a deep link string into structured data */\n parseDeepLink: (link: string) => ParsedDeepLink | null;\n /** Handle a deep link click β€” calls config.onDeepLink or config.onOpenDicom */\n handleDeepLink: (link: string) => void;\n /** Check if a string contains deep links */\n containsDeepLink: (text: string) => boolean;\n /** Extract all deep links from a message body */\n extractDeepLinks: (text: string) => ParsedDeepLink[];\n}\n\n/**\n * Parses and handles natoe:// deep links in messages.\n *\n * Supported formats:\n * natoe://order/4521 β†’ opens order detail\n * natoe://report/4521 β†’ opens report\n * natoe://dicom/4521 β†’ opens DICOM viewer (uses onOpenDicom callback)\n * natoe://study/4521 β†’ opens study detail\n */\nexport function useDeepLinks(): UseDeepLinksReturn {\n const { config } = useCollab();\n\n const parseDeepLink = useCallback((link: string): ParsedDeepLink | null => {\n if (!link.startsWith(DEEP_LINK_PREFIX)) return null;\n\n const path = link.slice(DEEP_LINK_PREFIX.length);\n const parts = path.split('/').filter(Boolean);\n\n if (parts.length < 2) return null;\n\n return {\n raw: link,\n path,\n resource: parts[0],\n id: parts[1],\n };\n }, []);\n\n const handleDeepLink = useCallback(\n (link: string) => {\n const parsed = parseDeepLink(link);\n if (!parsed) return;\n\n // DICOM links use the dedicated callback\n if (parsed.resource === 'dicom' && config.onOpenDicom) {\n config.onOpenDicom(parsed.id, '');\n return;\n }\n\n // Everything else goes through the generic deep link handler\n if (config.onDeepLink) {\n config.onDeepLink(parsed.path);\n }\n },\n [parseDeepLink, config]\n );\n\n const containsDeepLink = useCallback((text: string): boolean => {\n return text.includes(DEEP_LINK_PREFIX);\n }, []);\n\n const extractDeepLinks = useCallback(\n (text: string): ParsedDeepLink[] => {\n // Match natoe://path/segments patterns in text\n const regex = new RegExp(`${escapeRegex(DEEP_LINK_PREFIX)}[\\\\w/.-]+`, 'g');\n const matches = text.match(regex) || [];\n return matches.map(parseDeepLink).filter((link): link is ParsedDeepLink => link !== null);\n },\n [parseDeepLink]\n );\n\n return {\n parseDeepLink,\n handleDeepLink,\n containsDeepLink,\n extractDeepLinks,\n };\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import React from 'react';\n\n/**\n * \"Stack of slices\" glyph standing in for a DICOM study β€” three offset\n * rectangles to convey series/imaging without leaning on a specific anatomy.\n */\nexport function DicomIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"4\" y=\"4\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M7 7h13a2 2 0 0 1 2 2v11\" opacity=\"0.6\" />\n <circle cx=\"9\" cy=\"9.5\" r=\"1.2\" fill={color} stroke=\"none\" />\n <path d=\"M5 14l3-3 4 4 2-2 3 3\" />\n </svg>\n );\n}\n","import React from 'react';\n\n/**\n * Two-figure \"users\" glyph β€” used to surface the participant count on the\n * chat header. Stroke-based to match the sibling DicomIcon in the case\n * card's action row, sized to the same 18px default as the other inline\n * icons.\n */\nexport function PeopleIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\" />\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M22 21v-2a4 4 0 0 0-3-3.87\" />\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function BackIcon({ size = 22, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\" />\n </svg>\n );\n}\n","import React from 'react';\nimport { buildChannelName, cleanChannelName } from '../core/channelName';\nimport { DicomIcon } from './icons/DicomIcon';\nimport { PeopleIcon } from './icons/PeopleIcon';\nimport { BackIcon } from './icons/BackIcon';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SIZE,\n SPACE,\n} from '../core/theme';\nimport type { PatientData, Participant } from '../core/types';\n\ninterface PatientHeaderProps {\n patientData: PatientData;\n participants: Participant[];\n onOpenDicom?: () => void;\n onOpenSettings?: () => void;\n /** When set, renders a back-arrow button (compact inbox returning to list) */\n onBack?: () => void;\n /** Suppress the channel name row β€” use when the name is already shown in a parent title bar */\n hideName?: boolean;\n /** Override the displayed name β€” use the stored conversation.name to avoid reconstructing from patientData components */\n displayName?: string;\n className?: string;\n}\n\ninterface MetaItem {\n /** Stable key per slot (the field name), so React can dedupe even if\n * two unrelated slots happen to have the same value. */\n key: string;\n /** Uppercase label that sits above the value (\"AGE / SEX\", \"LAB\"). */\n label: string;\n /** The rendered value (\"54 Β· M\", \"Beachside Lab\", \"Knee\"). */\n value: string;\n}\n\n/**\n * Pick the most trustworthy name to show in the header.\n *\n * When `patientData` carries both labName and displayOrderId, the locally\n * built \"<patient> - <lab> - <last4>\" is guaranteed complete (CollabInbox's\n * buildPatientData merges these in from the inbox row's canonical name).\n * In that case prefer it over the server-supplied `displayName` β€” that way\n * the chat header always matches the string the user just clicked on in the\n * inbox, even if the backend's preview endpoint happens to return a less\n * complete `conversation.name` than the list endpoint did.\n *\n * Otherwise (e.g. host passed a stub PatientData without lab info), trust\n * the server's `displayName` if present, falling back to whatever the local\n * builder can manage.\n */\nfunction resolveDisplayName(patientData: PatientData, displayName?: string): string {\n const localComplete = !!patientData.labName && !!patientData.displayOrderId;\n if (localComplete) return buildChannelName(patientData);\n // Server-supplied names from older conversations may have been persisted\n // with an empty lab segment (\"Patient - - 1234\"). Collapse those before\n // rendering so the empty middle doesn't leak into the UI.\n return cleanChannelName(displayName) || buildChannelName(patientData);\n}\n\n/**\n * \"Case card\" header that sits below the window title bar. Tinted blue-50\n * background to set it apart from the conversation body. Renders a row\n * of labelled key-value columns (label uppercase on top, value below) for\n * the clinical context the host passed in, with the action buttons\n * (View DICOM + Settings) right-aligned.\n *\n * Used in two layouts:\n * - Popup path (`hideName=true`): the surrounding title bar already\n * shows the patient name, so we render the case card only.\n * - Compact-inbox path (`hideName=false`): the panel is a full-page\n * experience and there's no outer title, so we still show the name +\n * back button stacked above the case card.\n */\nexport function PatientHeader({\n patientData,\n participants,\n onOpenDicom,\n onOpenSettings,\n onBack,\n hideName = false,\n displayName,\n className,\n}: PatientHeaderProps) {\n const hasDicom = !!(patientData.studyId && patientData.storageId);\n\n const meta: MetaItem[] = [];\n // Age + Sex share one column with a centre-dot separator β€” natural\n // clinical shorthand. If only one is set, fall back to the single one.\n if (patientData.patientAge && patientData.patientSex) {\n meta.push({\n key: 'ageSex',\n label: 'Age / Sex',\n value: `${patientData.patientAge} Β· ${patientData.patientSex}`,\n });\n } else if (patientData.patientAge) {\n meta.push({ key: 'age', label: 'Age', value: String(patientData.patientAge) });\n } else if (patientData.patientSex) {\n meta.push({ key: 'sex', label: 'Sex', value: String(patientData.patientSex) });\n }\n if (patientData.studyType) {\n meta.push({ key: 'modality', label: 'Modality', value: patientData.studyType });\n }\n if (patientData.bodyParts && patientData.bodyParts.length > 0) {\n meta.push({\n key: 'body',\n label: 'Body part',\n value: patientData.bodyParts.join(', '),\n });\n }\n // Referring physician deliberately omitted from the case card β€” kept\n // off the chat surface to reduce visual density. Still available in\n // the order detail view.\n\n const hasActions = (hasDicom && onOpenDicom) || onOpenSettings;\n\n return (\n <div className={className} style={styles.container}>\n {!hideName && (\n <div style={styles.nameRow}>\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n style={styles.backButton}\n aria-label=\"Back to conversations\"\n title=\"Back to conversations\"\n >\n <BackIcon size={22} color={COLOR.neutral800} />\n </button>\n )}\n <span style={styles.nameText}>{resolveDisplayName(patientData, displayName)}</span>\n </div>\n )}\n\n <div style={styles.caseCard}>\n {/* Meta β€” stacked label-above-value columns flowing in a wrap-\n enabled row so they re-stack to a second row on narrow\n popups instead of overflowing horizontally. */}\n {meta.length > 0 && (\n <div style={styles.metaRow}>\n {meta.map((item) => (\n <div key={item.key} style={styles.metaCol}>\n <span style={styles.metaLabel}>{item.label}</span>\n <span style={styles.metaValue}>{item.value}</span>\n </div>\n ))}\n </div>\n )}\n\n {hasActions && (\n <div style={styles.actions}>\n {hasDicom && onOpenDicom && (\n <button\n onClick={onOpenDicom}\n style={styles.dicomButton}\n type=\"button\"\n aria-label=\"View DICOM study\"\n >\n <DicomIcon size={18} color={COLOR.primary} />\n <span>View DICOM</span>\n </button>\n )}\n {onOpenSettings && (\n <button\n onClick={onOpenSettings}\n style={styles.settingsIconButton}\n type=\"button\"\n aria-label={`Open channel settings (${participants.length} participants)`}\n title=\"Channel participants\"\n >\n <PeopleIcon size={18} color={COLOR.neutral600} />\n <span style={styles.participantCount}>{participants.length}</span>\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: COLOR.primaryBg,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n // Optional name row, only when `hideName` is false (compact-inbox path)\n nameRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S3} ${SPACE.S4} ${SPACE.S2}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n backgroundColor: COLOR.white,\n },\n backButton: {\n width: SIZE.controlIcon,\n height: SIZE.controlIcon,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginLeft: `-${SPACE.S2}`,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n nameText: {\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n color: COLOR.neutral900,\n lineHeight: LINE_HEIGHT.tight,\n letterSpacing: '-0.01em',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n // Case card: meta columns flowing in a wrap-row, actions stacked\n // below. Each meta column is a small label-above-value pair so the\n // user can scan field names quickly without a legend.\n caseCard: {\n display: 'flex',\n flexDirection: 'column',\n gap: SPACE.S3,\n padding: `${SPACE.S3} ${SPACE.S5}`,\n },\n // Wrap-row of stacked label/value columns. Compact column gap keeps\n // the row dense without crowding; row gap kicks in when columns\n // wrap to a second line on narrow popups.\n metaRow: {\n display: 'flex',\n flexWrap: 'wrap',\n columnGap: SPACE.S5,\n rowGap: SPACE.S2,\n minWidth: 0,\n },\n metaCol: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n minWidth: 0,\n },\n metaLabel: {\n fontSize: '11px',\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '0.06em',\n textTransform: 'uppercase' as const,\n color: COLOR.neutral500,\n whiteSpace: 'nowrap' as const,\n },\n metaValue: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral900,\n whiteSpace: 'nowrap' as const,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n maxWidth: '180px',\n },\n actions: {\n display: 'flex',\n gap: SPACE.S2,\n flexShrink: 0,\n },\n dicomButton: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n minHeight: SIZE.control,\n padding: `${SPACE.S2} 14px`,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n backgroundColor: COLOR.white,\n border: `1.5px solid ${COLOR.primary}`,\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n },\n // Channel-info button: people icon + participant count. Click opens the\n // channel settings overlay (kept on the same handler as before so hosts\n // don't have to re-wire β€” the affordance just looks like a \"members\"\n // pill now instead of a gear).\n settingsIconButton: {\n minHeight: SIZE.control,\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `0 ${SPACE.S3}`,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.lg,\n color: COLOR.neutral600,\n cursor: 'pointer',\n flexShrink: 0,\n },\n participantCount: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n fontVariantNumeric: 'tabular-nums',\n },\n};\n","import React from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { MessageSnapshot } from '../core/types';\n\ninterface ReplyQuoteBlockProps {\n snapshot: MessageSnapshot;\n /** True when rendered inside an own-message bubble (affects color contrast) */\n inOwnBubble?: boolean;\n /** Called when user clicks the quote β€” host can scroll to the original message */\n onClick?: (messageId: string) => void;\n className?: string;\n}\n\n/**\n * Rendered inside a MessageBubble when the message is a reply.\n * Shows a compact quote of the original message.\n */\nexport function ReplyQuoteBlock({\n snapshot,\n inOwnBubble = false,\n onClick,\n className,\n}: ReplyQuoteBlockProps) {\n // The quote must clearly differ from the bubble it sits inside, otherwise\n // the visual treatment disappears and replies read as plain messages.\n // Own bubbles use a translucent white wash on the brand-blue background;\n // others' bubbles (neutral100) get a clean white card so the quote pops.\n const baseBg = inOwnBubble ? 'rgba(255,255,255,0.22)' : COLOR.white;\n const barColor = inOwnBubble ? COLOR.white : COLOR.primary;\n const nameColor = inOwnBubble ? COLOR.white : COLOR.primary;\n const bodyColor = inOwnBubble ? 'rgba(255,255,255,0.9)' : COLOR.neutral700;\n\n const preview = renderSnapshotPreview(snapshot);\n\n return (\n <div\n className={className}\n style={{ ...styles.container, backgroundColor: baseBg }}\n onClick={() => onClick?.(snapshot.messageId)}\n role={onClick ? 'button' : undefined}\n tabIndex={onClick ? 0 : undefined}\n >\n <div style={{ ...styles.bar, backgroundColor: barColor }} />\n <div style={styles.content}>\n <span style={{ ...styles.senderName, color: nameColor }}>{snapshot.senderName}</span>\n <span style={{ ...styles.body, color: bodyColor }}>{preview}</span>\n </div>\n </div>\n );\n}\n\nfunction renderSnapshotPreview(snapshot: MessageSnapshot): string {\n switch (snapshot.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return 'πŸ“· Image';\n case 'file':\n return 'πŸ“Ž File';\n case 'deep_link':\n return `πŸ”— ${snapshot.body}`;\n default: {\n const body = snapshot.body || '';\n return body.length > 80 ? `${body.slice(0, 80)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S2}`,\n marginBottom: SPACE.S1,\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n maxWidth: '100%',\n },\n bar: {\n width: '3px',\n borderRadius: '2px',\n flexShrink: 0,\n },\n content: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1px',\n minWidth: 0,\n overflow: 'hidden',\n },\n senderName: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n lineHeight: LINE_HEIGHT.tight,\n },\n body: {\n fontSize: FONT_SIZE.xs,\n lineHeight: LINE_HEIGHT.tight,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n};\n","import React, { useState } from 'react';\nimport { COLOR, FONT_SIZE, FONT_WEIGHT, SPACE } from '../core/theme';\nimport type { Participant } from '../core/types';\n\ninterface SeenByIndicatorProps {\n /** User IDs who have read the message */\n readBy: string[];\n /** All participants in the conversation β€” used to resolve names */\n participants: Participant[];\n /** Current user ID (excluded from the display) */\n currentUserId: string;\n /** Message sender ID (excluded from the display) */\n senderId: string;\n className?: string;\n}\n\n/**\n * WhatsApp-style \"Seen by\" indicator shown under own messages.\n * Shows up to 3 names inline; if more, shows remainder count with a tap-to-expand.\n *\n * Only renders when the current user is the sender (seen-by on others' messages\n * is redundant β€” they obviously saw their own message).\n */\nexport function SeenByIndicator({\n readBy,\n participants,\n currentUserId,\n senderId,\n className,\n}: SeenByIndicatorProps) {\n const [expanded, setExpanded] = useState(false);\n\n // Only show on own messages\n if (senderId !== currentUserId) return null;\n\n const seenByOthers = readBy\n .filter((id) => id !== currentUserId && id !== senderId)\n .map((id) => participants.find((p) => p.userId === id))\n .filter((p): p is Participant => !!p);\n\n if (seenByOthers.length === 0) return null;\n\n const displayCount = expanded ? seenByOthers.length : Math.min(3, seenByOthers.length);\n const shown = seenByOthers.slice(0, displayCount);\n const remainder = seenByOthers.length - displayCount;\n\n return (\n <div className={className} style={styles.container}>\n <span style={styles.checkmark}>βœ“βœ“</span>\n <span style={styles.label}>Seen by {shown.map((p) => p.userName ?? 'User').join(', ')}</span>\n {remainder > 0 && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n setExpanded(true);\n }}\n style={styles.moreButton}\n type=\"button\"\n >\n +{remainder}\n </button>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n marginTop: '2px',\n fontSize: FONT_SIZE.xs,\n opacity: 0.85,\n },\n checkmark: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n },\n label: {\n fontSize: FONT_SIZE.xs,\n color: 'inherit',\n },\n moreButton: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: 'inherit',\n backgroundColor: 'transparent',\n border: 'none',\n padding: 0,\n cursor: 'pointer',\n textDecoration: 'underline',\n },\n};\n","import React from 'react';\n\nexport function ReplyIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function PinIcon({ size = 14, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function CopyIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n}\n","import React from 'react';\n\n/**\n * Vertical \"more options\" glyph β€” three stacked dots. Used as the\n * always-visible trigger for the per-message actions popover.\n */\nexport function MoreIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"5\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"19\" r=\"2\" />\n </svg>\n );\n}\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ReplyIcon } from './icons/ReplyIcon';\nimport { PinIcon } from './icons/PinIcon';\nimport { CopyIcon } from './icons/CopyIcon';\nimport { MoreIcon } from './icons/MoreIcon';\nimport {\n COLOR,\n FONT_SIZE,\n RADIUS,\n SHADOW,\n SIZE,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface MessageActionsMenuProps {\n message: Message;\n onReply: (message: Message) => void;\n onPin: (messageId: string) => void;\n onUnpin: (messageId: string) => void;\n onCopy?: (text: string) => void;\n /** Whether we've hit the pin limit β€” if true, pin is disabled */\n pinDisabled?: boolean;\n /** Anchor the popover to the right edge of the trigger (use for messages on the left side of the panel) */\n anchorRight?: boolean;\n className?: string;\n}\n\n/** Pixels of breathing room kept between the menu and any viewport edge. */\nconst VIEWPORT_MARGIN = 8;\n/** Gap between the trigger and the menu when shown above or below. */\nconst TRIGGER_GAP = 4;\n\n/**\n * Self-contained \"β‹―\" trigger + popover for per-message actions. The menu is\n * rendered into a portal on document.body and positioned via getBoundingClientRect,\n * so it escapes any ancestor overflow:hidden (the floating CollabPopup\n * container) and flips above the trigger when there's no room below.\n *\n * Closes on outside-click, Escape, window resize, or scroll outside the menu.\n */\nexport function MessageActionsMenu({\n message,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n pinDisabled = false,\n anchorRight = false,\n className,\n}: MessageActionsMenuProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const isPinned = !!message.isPinned;\n const canCopy = message.type === 'text' && !!message.body;\n\n // Compute placement after open β€” measure both trigger and menu, prefer\n // below the trigger but flip up when the menu would clip the viewport bottom.\n // Horizontally we honor `anchorRight` as a preference and then clamp to\n // viewport edges so the menu never hangs off-screen on narrow surfaces\n // (e.g. the 380px floating popup).\n useLayoutEffect(() => {\n if (!isOpen) {\n setCoords(null);\n return;\n }\n const trigger = triggerRef.current;\n const menu = menuRef.current;\n if (!trigger || !menu) return;\n\n const triggerRect = trigger.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const spaceBelow = vh - triggerRect.bottom;\n const spaceAbove = triggerRect.top;\n const placeAbove =\n spaceBelow < menuRect.height + TRIGGER_GAP + VIEWPORT_MARGIN &&\n spaceAbove > spaceBelow;\n\n const top = placeAbove\n ? triggerRect.top - menuRect.height - TRIGGER_GAP\n : triggerRect.bottom + TRIGGER_GAP;\n\n const preferredLeft = anchorRight\n ? triggerRect.right - menuRect.width\n : triggerRect.left;\n const left = Math.max(\n VIEWPORT_MARGIN,\n Math.min(preferredLeft, vw - menuRect.width - VIEWPORT_MARGIN)\n );\n const clampedTop = Math.max(\n VIEWPORT_MARGIN,\n Math.min(top, vh - menuRect.height - VIEWPORT_MARGIN)\n );\n\n setCoords({ top: clampedTop, left });\n }, [isOpen, anchorRight]);\n\n // Dismissal: outside-click, Escape, window resize, scroll outside the menu.\n // The menu is portaled so it's not a descendant of the wrapper β€” outside\n // checks have to consult both the trigger and the menu nodes.\n useEffect(() => {\n if (!isOpen) return;\n\n const isInside = (node: Node | null) =>\n !!node &&\n (triggerRef.current?.contains(node) === true ||\n menuRef.current?.contains(node) === true);\n\n const handleClick = (e: MouseEvent) => {\n if (!isInside(e.target as Node)) setIsOpen(false);\n };\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n };\n const handleScroll = (e: Event) => {\n if (!isInside(e.target as Node)) setIsOpen(false);\n };\n const handleResize = () => setIsOpen(false);\n\n document.addEventListener('mousedown', handleClick);\n document.addEventListener('keydown', handleKey);\n window.addEventListener('resize', handleResize);\n // Capture-phase so we see scrolls on any ancestor of the trigger (the\n // chat list, the popup, the page) without each one needing to bubble.\n window.addEventListener('scroll', handleScroll, true);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n document.removeEventListener('keydown', handleKey);\n window.removeEventListener('resize', handleResize);\n window.removeEventListener('scroll', handleScroll, true);\n };\n }, [isOpen]);\n\n const run = (fn: () => void) => {\n setIsOpen(false);\n fn();\n };\n\n const menu = isOpen ? (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label=\"Message actions\"\n style={{\n ...styles.menu,\n // Render off-screen on first paint so we can measure before placing,\n // then snap to computed coords on the next layout pass.\n top: coords?.top ?? -9999,\n left: coords?.left ?? -9999,\n visibility: coords ? 'visible' : 'hidden',\n }}\n >\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onReply(message))}\n style={styles.item}\n >\n <ReplyIcon size={18} color={COLOR.neutral700} />\n <span>Reply</span>\n </button>\n\n {isPinned ? (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onUnpin(message.id))}\n style={styles.item}\n >\n <PinIcon size={16} color={COLOR.neutral700} />\n <span>Unpin</span>\n </button>\n ) : (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onPin(message.id))}\n disabled={pinDisabled}\n style={{\n ...styles.item,\n ...(pinDisabled ? styles.itemDisabled : {}),\n }}\n title={pinDisabled ? 'Pin limit reached (max 3)' : undefined}\n >\n <PinIcon size={16} color={COLOR.neutral700} />\n <span>{pinDisabled ? 'Pin (limit reached)' : 'Pin'}</span>\n </button>\n )}\n\n {canCopy && onCopy && (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => run(() => onCopy(message.body))}\n style={styles.item}\n >\n <CopyIcon size={16} color={COLOR.neutral700} />\n <span>Copy text</span>\n </button>\n )}\n </div>\n ) : null;\n\n return (\n <div className={className} style={styles.wrapper}>\n <button\n ref={triggerRef}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsOpen((v) => !v);\n }}\n aria-label=\"Message actions\"\n aria-haspopup=\"menu\"\n aria-expanded={isOpen ? 'true' : 'false'}\n title=\"Message actions\"\n style={styles.trigger}\n >\n <MoreIcon size={18} color={COLOR.neutral600} />\n </button>\n {menu && typeof document !== 'undefined' ? createPortal(menu, document.body) : null}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n wrapper: {\n position: 'relative',\n display: 'inline-block',\n },\n // Pill-shaped trigger matching the prototype's `.nc-msg-act` style β€”\n // always visible (touch-friendly) rather than hover-only.\n trigger: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '32px',\n height: '32px',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: '999px',\n cursor: 'pointer',\n color: COLOR.neutral600,\n transition: 'background-color 120ms ease, color 120ms ease, border-color 120ms ease',\n },\n menu: {\n position: 'fixed',\n minWidth: '200px',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.lg,\n boxShadow: SHADOW.popover,\n padding: '6px',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '2px',\n // Above the floating popup (z-index dialog) but below any future modal.\n zIndex: Z_INDEX.menu,\n },\n item: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n width: '100%',\n minHeight: SIZE.control,\n padding: `10px ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral700,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n textAlign: 'left' as const,\n fontFamily: 'inherit',\n },\n itemDisabled: {\n color: COLOR.neutral400,\n cursor: 'not-allowed',\n },\n};\n","import React from 'react';\n\nexport function FileIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function AlertIcon({ size = 14, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\" />\n </svg>\n );\n}\n","import React from 'react';\nimport { COLOR } from '../core/theme';\n\ninterface SpinnerProps {\n size?: number;\n color?: string;\n thickness?: number;\n}\n\n/**\n * Lightweight indeterminate spinner β€” pure CSS, no animation library.\n * Used for \"Loading earlier messages\" and any other inline progress affordance.\n */\nexport function Spinner({ size = 16, color = COLOR.neutral500, thickness = 2 }: SpinnerProps) {\n return (\n <span\n role=\"status\"\n aria-label=\"Loading\"\n style={{\n display: 'inline-block',\n width: size,\n height: size,\n border: `${thickness}px solid ${color}33`,\n borderTopColor: color,\n borderRadius: '50%',\n animation: 'natoe-colab-spin 800ms linear infinite',\n verticalAlign: 'middle',\n }}\n />\n );\n}\n\n// Inject keyframes once per page β€” repeat insert is a no-op.\nif (typeof document !== 'undefined') {\n const existing = document.getElementById('natoe-colab-spin-keyframes');\n if (!existing) {\n const style = document.createElement('style');\n style.id = 'natoe-colab-spin-keyframes';\n style.textContent = `@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }`;\n document.head.appendChild(style);\n }\n}\n","import React from 'react';\nimport { ReplyQuoteBlock } from './ReplyQuoteBlock';\nimport { SeenByIndicator } from './SeenByIndicator';\nimport { MessageActionsMenu } from './MessageActionsMenu';\nimport { FileIcon } from './icons/FileIcon';\nimport { PinIcon } from './icons/PinIcon';\nimport { AlertIcon } from './icons/AlertIcon';\nimport { Spinner } from './Spinner';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message, Participant, UserRole } from '../core/types';\nimport { DEEP_LINK_PREFIX } from '../core/constants';\n\nconst ROLE_LABELS: Record<UserRole, string> = {\n radiologist: 'Radiologist',\n lab: 'Imaging Center',\n physician: 'Physician',\n admin: 'Admin',\n};\n\ninterface MessageBubbleProps {\n message: Message;\n isOwn: boolean;\n /** Participants list β€” needed for SeenByIndicator */\n participants?: Participant[];\n /** Current user ID β€” needed for SeenByIndicator */\n currentUserId?: string;\n /** Show \"seen by\" indicator under own messages (default true β€” inline disables this) */\n showSeenBy?: boolean;\n onDeepLinkClick?: (link: string) => void;\n onReply?: (message: Message) => void;\n onPin?: (messageId: string) => void;\n onUnpin?: (messageId: string) => void;\n onCopy?: (text: string) => void;\n onReplyJumpTo?: (messageId: string) => void;\n /** Re-send a previously-failed message (own bubbles only) */\n onRetry?: (messageId: string) => void;\n /** True if pin limit reached β€” disables pin action */\n pinDisabled?: boolean;\n className?: string;\n}\n\nexport function MessageBubble({\n message,\n isOwn,\n participants = [],\n currentUserId = '',\n showSeenBy = true,\n onDeepLinkClick,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n onReplyJumpTo,\n onRetry,\n pinDisabled = false,\n className,\n}: MessageBubbleProps) {\n if (message.type === 'system') {\n return <SystemBubble message={message} />;\n }\n\n const hasActions = !!(onReply || onPin || onUnpin || onCopy);\n const actionsSlot = hasActions ? (\n <div style={styles.actionsSlot}>\n <MessageActionsMenu\n message={message}\n onReply={onReply ?? (() => {})}\n onPin={onPin ?? (() => {})}\n onUnpin={onUnpin ?? (() => {})}\n onCopy={onCopy}\n pinDisabled={pinDisabled}\n anchorRight={!isOwn}\n />\n </div>\n ) : null;\n\n return (\n <div\n className={className}\n style={{\n ...styles.wrapper,\n justifyContent: isOwn ? 'flex-end' : 'flex-start',\n }}\n >\n {isOwn && actionsSlot}\n <div style={styles.bubbleWrapper}>\n {/* Author row above the bubble (only for others' messages).\n The avatar leads in with its role-colored fill; the bubble\n sits directly below, sharing the same left edge as the\n avatar β€” a cleaner ownership cue than baking the sender\n name inside the bubble itself. */}\n {!isOwn && (\n <div style={styles.authorRow}>\n <span\n style={{\n ...styles.authorAvatar,\n backgroundColor: roleColor(message.senderRole),\n }}\n aria-hidden=\"true\"\n >\n {computeInitials(message.senderName)}\n </span>\n <span style={styles.authorName}>{message.senderName}</span>\n <RoleBadge role={message.senderRole} />\n </div>\n )}\n\n <div\n style={{\n ...styles.bubble,\n ...(isOwn ? styles.ownBubble : styles.otherBubble),\n }}\n >\n {/* Pinned indicator */}\n {message.isPinned && (\n <div\n style={{\n ...styles.pinnedBadge,\n ...(isOwn ? styles.pinnedBadgeOwn : styles.pinnedBadgeOther),\n }}\n >\n <PinIcon size={12} />\n <span>Pinned</span>\n </div>\n )}\n\n {/* Reply quote (when this message is a reply) */}\n {message.replyToSnapshot && (\n <ReplyQuoteBlock\n snapshot={message.replyToSnapshot}\n inOwnBubble={isOwn}\n onClick={onReplyJumpTo}\n />\n )}\n\n {/* Message content by type */}\n {message.type === 'text' && <TextContent body={message.body} onDeepLinkClick={onDeepLinkClick} />}\n {message.type === 'audio' && <AudioContent mediaUrl={message.mediaUrl} duration={message.mediaDuration} />}\n {message.type === 'image' && <ImageContent mediaUrl={message.mediaUrl} fileName={message.fileName} />}\n {message.type === 'file' && <FileContent mediaUrl={message.mediaUrl} fileName={message.fileName} />}\n {message.type === 'deep_link' && (\n <DeepLinkContent body={message.body} metadata={message.metadata} onDeepLinkClick={onDeepLinkClick} />\n )}\n\n {/* Footer: time + delivery state */}\n <div style={styles.bubbleFoot}>\n <span style={styles.timestamp}>{formatTime(message.insertedAt)}</span>\n\n {isOwn && message.status === 'sending' && (\n <span style={styles.footStatus}>\n <Spinner size={11} color=\"rgba(255,255,255,0.85)\" />\n <span>Sending…</span>\n </span>\n )}\n {isOwn && message.status === 'failed' && (\n <span style={styles.footStatusFailed}>\n <AlertIcon size={11} color=\"#fecaca\" />\n <span>Not sent</span>\n {onRetry && (\n <button\n type=\"button\"\n onClick={() => onRetry(message.id)}\n style={styles.retryButton}\n aria-label=\"Retry sending message\"\n >\n Retry\n </button>\n )}\n </span>\n )}\n {showSeenBy && isOwn && !message.status && (\n <SeenByIndicator\n readBy={message.readBy ?? []}\n participants={participants}\n currentUserId={currentUserId}\n senderId={message.senderId}\n />\n )}\n </div>\n </div>\n </div>\n {!isOwn && actionsSlot}\n </div>\n );\n}\n\nfunction computeInitials(name: string): string {\n return (\n name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((p) => p[0]?.toUpperCase() ?? '')\n .join('') || '?'\n );\n}\n\nfunction roleColor(role: UserRole): string {\n // Cool-only palette β€” keep role tags / author avatars in the blue\n // family so the chat screen reads as a single tonal range. Roles\n // stay distinguishable via tone (sky vs brand vs indigo vs slate)\n // rather than primary-color contrast (no greens / reds / purples).\n switch (role) {\n case 'radiologist':\n return '#4f46e5'; // indigo (blue-leaning)\n case 'lab':\n return '#2563eb'; // brand blue\n case 'physician':\n return '#0284c7'; // sky\n case 'admin':\n return '#64748b'; // slate (muted)\n default:\n return '#6b7280';\n }\n}\n\n// ── Sub-components ──\n\nfunction TextContent({ body, onDeepLinkClick }: { body: string; onDeepLinkClick?: (link: string) => void }) {\n if (body.includes(DEEP_LINK_PREFIX)) {\n const parts = body.split(new RegExp(`(${escapeRegex(DEEP_LINK_PREFIX)}[\\\\w/.-]+)`, 'g'));\n return (\n <p style={styles.textBody}>\n {parts.map((part, i) =>\n part.startsWith(DEEP_LINK_PREFIX) ? (\n <a\n key={i}\n onClick={(e) => {\n e.preventDefault();\n onDeepLinkClick?.(part);\n }}\n href=\"#\"\n style={styles.deepLink}\n >\n {part}\n </a>\n ) : (\n <span key={i}>{part}</span>\n )\n )}\n </p>\n );\n }\n\n return <p style={styles.textBody}>{body}</p>;\n}\n\nfunction AudioContent({ mediaUrl, duration }: { mediaUrl?: string; duration?: number }) {\n if (!mediaUrl) return null;\n\n return (\n <div style={styles.audioContainer}>\n <audio controls preload=\"metadata\" style={styles.audioPlayer}>\n <source src={mediaUrl} />\n </audio>\n {duration != null && <span style={styles.audioDuration}>{formatDuration(duration)}</span>}\n </div>\n );\n}\n\nfunction ImageContent({ mediaUrl, fileName }: { mediaUrl?: string; fileName?: string }) {\n if (!mediaUrl) return null;\n\n return (\n <a href={mediaUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <img src={mediaUrl} alt={fileName || 'Image'} style={styles.imagePreview} />\n </a>\n );\n}\n\nfunction FileContent({ mediaUrl, fileName }: { mediaUrl?: string; fileName?: string }) {\n if (!mediaUrl) return null;\n\n return (\n <a href={mediaUrl} target=\"_blank\" rel=\"noopener noreferrer\" style={styles.fileLink}>\n <FileIcon size={20} />\n <span style={styles.fileName}>{fileName || 'Download file'}</span>\n </a>\n );\n}\n\nfunction DeepLinkContent({\n body,\n metadata,\n onDeepLinkClick,\n}: {\n body: string;\n metadata?: Record<string, unknown>;\n onDeepLinkClick?: (link: string) => void;\n}) {\n const path = metadata?.path as string | undefined;\n\n return (\n <div\n style={styles.deepLinkCard}\n onClick={() => path && onDeepLinkClick?.(`${DEEP_LINK_PREFIX}${path}`)}\n >\n <span style={styles.deepLinkLabel}>{body}</span>\n {path && <span style={styles.deepLinkPath}>{DEEP_LINK_PREFIX}{path}</span>}\n </div>\n );\n}\n\nfunction SystemBubble({ message }: { message: Message }) {\n return (\n <div style={styles.systemWrapper}>\n <span style={styles.systemPill}>\n <span>{message.body}</span>\n <span style={styles.systemTime}>{formatTime(message.insertedAt)}</span>\n </span>\n </div>\n );\n}\n\nfunction RoleBadge({ role }: { role: UserRole }) {\n // Solid role-coloured pill with white text β€” keeps the same palette\n // values, just inverts the treatment from tinted-on-light to bold.\n return (\n <span style={{ ...styles.roleBadge, backgroundColor: roleColor(role) }}>\n {ROLE_LABELS[role] ?? role}\n </span>\n );\n}\n\n// ── Helpers ──\n\nfunction formatTime(iso: string): string {\n try {\n return new Date(iso).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n } catch {\n return '';\n }\n}\n\nfunction formatDuration(seconds: number): string {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// ── Styles ──\n\nconst styles: Record<string, React.CSSProperties> = {\n wrapper: {\n display: 'flex',\n alignItems: 'flex-end',\n gap: SPACE.S1,\n marginBottom: SPACE.S3,\n paddingLeft: SPACE.S4,\n paddingRight: SPACE.S4,\n },\n bubbleWrapper: {\n position: 'relative',\n maxWidth: '78%',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n },\n actionsSlot: {\n flexShrink: 0,\n alignSelf: 'flex-end',\n },\n // Author row above the bubble β€” only rendered for others' messages.\n authorRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n authorAvatar: {\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n color: COLOR.white,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.bold,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n letterSpacing: '0.02em',\n },\n authorName: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n },\n bubble: {\n padding: `${SPACE.S3} ${SPACE.S4}`,\n borderRadius: '18px',\n wordBreak: 'break-word',\n border: '1px solid transparent',\n },\n ownBubble: {\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n borderColor: COLOR.primary,\n borderBottomRightRadius: '6px',\n },\n otherBubble: {\n backgroundColor: COLOR.neutral100,\n color: COLOR.neutral900,\n borderColor: COLOR.neutral200,\n borderBottomLeftRadius: '6px',\n },\n pinnedBadge: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n fontWeight: FONT_WEIGHT.bold,\n marginBottom: SPACE.S2,\n padding: `2px ${SPACE.S2}`,\n borderRadius: '999px',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n pinnedBadgeOther: {\n color: '#b8680f',\n backgroundColor: '#fff7e0',\n },\n pinnedBadgeOwn: {\n color: '#fff4d6',\n backgroundColor: 'rgba(255, 255, 255, 0.2)',\n },\n roleBadge: {\n fontSize: '10px',\n fontWeight: FONT_WEIGHT.bold,\n padding: '2px 7px',\n borderRadius: RADIUS.sm,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n color: COLOR.white,\n flexShrink: 0,\n },\n textBody: {\n margin: 0,\n fontSize: FONT_SIZE.md,\n lineHeight: 1.5,\n },\n bubbleFoot: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: SPACE.S2,\n marginTop: SPACE.S2,\n fontSize: '11px',\n opacity: 0.85,\n },\n timestamp: {\n fontSize: '11px',\n color: 'inherit',\n fontVariantNumeric: 'tabular-nums',\n },\n footStatus: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n },\n footStatusFailed: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n },\n retryButton: {\n background: 'transparent',\n border: 'none',\n color: COLOR.white,\n fontWeight: FONT_WEIGHT.semibold,\n fontSize: '11px',\n textDecoration: 'underline',\n cursor: 'pointer',\n padding: `0 ${SPACE.S1}`,\n },\n audioContainer: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n audioPlayer: {\n height: '32px',\n maxWidth: '220px',\n },\n audioDuration: {\n fontSize: FONT_SIZE.xs,\n opacity: 0.7,\n whiteSpace: 'nowrap' as const,\n },\n imagePreview: {\n maxWidth: '240px',\n maxHeight: '180px',\n borderRadius: RADIUS.md,\n objectFit: 'cover' as const,\n cursor: 'pointer',\n },\n fileLink: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n textDecoration: 'none',\n color: 'inherit',\n padding: `${SPACE.S1} 0`,\n },\n fileName: {\n fontSize: FONT_SIZE.sm,\n textDecoration: 'underline',\n },\n deepLink: {\n color: COLOR.primary,\n textDecoration: 'underline',\n cursor: 'pointer',\n },\n deepLinkCard: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '2px',\n padding: SPACE.S2,\n backgroundColor: COLOR.primaryBg,\n borderRadius: RADIUS.md,\n border: `1px solid ${COLOR.primaryBg}`,\n cursor: 'pointer',\n },\n deepLinkLabel: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.primaryFg,\n },\n deepLinkPath: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n fontFamily: 'monospace',\n },\n systemWrapper: {\n display: 'flex',\n justifyContent: 'center',\n margin: `${SPACE.S2} 0`,\n },\n systemPill: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `5px ${SPACE.S3}`,\n backgroundColor: COLOR.neutral100,\n borderRadius: '999px',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n },\n systemTime: {\n fontSize: '11px',\n color: COLOR.neutral400,\n fontVariantNumeric: 'tabular-nums',\n },\n};\n","import React from 'react';\n\n/**\n * Soft, friendly empty-state illustration for the chat thread.\n * Two overlapping speech bubbles + a subtle background circle. Pure SVG, no\n * external assets so it renders consistently across hosts.\n */\nexport function ChatIllustration({ size = 96 }: { size?: number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 120 120\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"60\" cy=\"60\" r=\"56\" fill=\"#eff6ff\" />\n <path\n 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\"\n fill=\"#ffffff\"\n stroke=\"#2563eb\"\n strokeWidth=\"2.5\"\n />\n <path\n 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\"\n fill=\"#dbeafe\"\n stroke=\"#2563eb\"\n strokeWidth=\"2.5\"\n />\n <circle cx=\"48\" cy=\"53\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"58\" cy=\"53\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"68\" cy=\"68\" r=\"2.5\" fill=\"#2563eb\" />\n <circle cx=\"78\" cy=\"68\" r=\"2.5\" fill=\"#2563eb\" />\n </svg>\n );\n}\n","/**\n * Shared date/time labels for the chat UI.\n *\n * Two surfaces consume these:\n * - The inbox row's right-side timestamp ({@link formatInboxTimestamp})\n * - The in-chat day divider pill ({@link formatDayDivider})\n *\n * Bucketing is identical between them, so a conversation labeled \"Tuesday\"\n * in the inbox is grouped under a \"Tuesday\" pill inside its chat β€” no\n * drift between surfaces.\n *\n * Format choices:\n * - Full date: \"15 May 2026\" (fixed English short month, day, year)\n * - Weekday: \"Tuesday\" (fixed English long weekday)\n * - Time: locale-defaulted (respects the user's OS region)\n */\n\nconst SHORT_MONTHS = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\n];\n\nconst LONG_WEEKDAYS = [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',\n];\n\nconst ONE_DAY_MS = 86_400_000;\n\nfunction parseSafe(iso: string): Date | null {\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n/** Returns the start of the day for the given date (local time). */\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Number of calendar days between two dates (local time). Negative if a < b. */\nfunction daysBetween(a: Date, b: Date): number {\n return Math.floor((startOfDay(a).getTime() - startOfDay(b).getTime()) / ONE_DAY_MS);\n}\n\nfunction formatFullDate(d: Date): string {\n return `${d.getDate()} ${SHORT_MONTHS[d.getMonth()]} ${d.getFullYear()}`;\n}\n\nfunction formatLocaleTime(d: Date): string {\n // Locale-default time. Tries to match the user's OS preference for 12h vs\n // 24h. Falls back to a manual 12h format if Intl is unavailable.\n try {\n return d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n } catch {\n const h = d.getHours();\n const m = d.getMinutes().toString().padStart(2, '0');\n const suffix = h >= 12 ? 'PM' : 'AM';\n const h12 = ((h + 11) % 12) + 1;\n return `${h12}:${m} ${suffix}`;\n }\n}\n\n/**\n * Inbox row timestamp (right-edge of each conversation row).\n *\n * today β†’ \"9:42 PM\"\n * yesterday β†’ \"Yesterday\"\n * last 7 days β†’ weekday name (\"Tuesday\")\n * older β†’ \"15 May 2026\"\n */\nexport function formatInboxTimestamp(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n\n const diffDays = daysBetween(new Date(), d);\n\n if (diffDays === 0) return formatLocaleTime(d);\n if (diffDays === 1) return 'Yesterday';\n if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];\n return formatFullDate(d);\n}\n\n/**\n * In-chat day divider pill text.\n *\n * today β†’ \"Today\"\n * yesterday β†’ \"Yesterday\"\n * last 7 days β†’ weekday name (\"Tuesday\")\n * older β†’ \"15 May 2026\"\n */\nexport function formatDayDivider(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n\n const diffDays = daysBetween(new Date(), d);\n\n if (diffDays === 0) return 'Today';\n if (diffDays === 1) return 'Yesterday';\n if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];\n return formatFullDate(d);\n}\n\n/**\n * Stable day-bucket key for grouping messages. Two messages with the same\n * key belong under the same day divider.\n */\nexport function dayBucketKey(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = parseSafe(iso);\n if (!d) return '';\n return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;\n}\n","import React, { useEffect, useLayoutEffect, useRef, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport { MessageBubble } from './MessageBubble';\nimport { Spinner } from './Spinner';\nimport { ChatIllustration } from './icons/ChatIllustration';\nimport { dayBucketKey, formatDayDivider } from '../core/dateLabels';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SHADOW,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Message, Participant, TypingEvent } from '../core/types';\n\nexport interface MessageListHandle {\n /** Scroll to a specific message by ID (used by pin jump-to) */\n scrollToMessage: (messageId: string) => void;\n}\n\ninterface MessageListProps {\n messages: Message[];\n currentUserId: string;\n participants?: Participant[];\n showSeenBy?: boolean;\n typingUsers: TypingEvent[];\n hasMore: boolean;\n isLoading: boolean;\n onLoadMore: () => void;\n onDeepLinkClick?: (link: string) => void;\n onMessageVisible?: (messageId: string) => void;\n onReply?: (message: Message) => void;\n onPin?: (messageId: string) => void;\n onUnpin?: (messageId: string) => void;\n onCopy?: (text: string) => void;\n /** Retry a failed message (own bubbles only) */\n onRetry?: (messageId: string) => void;\n pinDisabled?: boolean;\n className?: string;\n}\n\nexport const MessageList = forwardRef<MessageListHandle, MessageListProps>(function MessageList(\n {\n messages,\n currentUserId,\n participants = [],\n showSeenBy = true,\n typingUsers,\n hasMore,\n isLoading,\n onLoadMore,\n onDeepLinkClick,\n onMessageVisible,\n onReply,\n onPin,\n onUnpin,\n onCopy,\n onRetry,\n pinDisabled,\n className,\n },\n ref\n) {\n const containerRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const prevMessageCount = useRef(messages.length);\n // Tracks whether we've performed the one-time jump-to-bottom on\n // initial load. Without this the auto-scroll effect only fires if the\n // user is \"already near bottom\" β€” which is never true at mount time,\n // so opening a chat would land on the oldest message instead of the\n // latest. CollabPanel keys the panel by orderId so this ref naturally\n // resets when the user switches conversations.\n const hasInitiallyScrolledRef = useRef(false);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToMessage: (messageId: string) => {\n const element = containerRef.current?.querySelector(`[data-message-id=\"${messageId}\"]`);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n // Brief flash to draw attention\n (element as HTMLElement).style.transition = 'background-color 200ms';\n (element as HTMLElement).style.backgroundColor = '#fef3c7';\n setTimeout(() => {\n (element as HTMLElement).style.backgroundColor = '';\n }, 800);\n }\n },\n }),\n []\n );\n\n // Initial positioning β€” runs once per mount, before paint.\n // - If any message is unread by the current user (their userId not\n // in readBy, and they didn't send it) β†’ scroll the FIRST such\n // message to the top of the visible area so the user resumes\n // where they left off.\n // - Otherwise β†’ jump to the bottom so the user sees the latest\n // exchange in a fully-read thread.\n //\n // useLayoutEffect (not useEffect) so the scroll happens before paint\n // β€” no flash of \"scrolled to top\" in between. Direct scrollTop\n // assignment instead of scrollIntoView because the popup has\n // overflow:hidden ancestors that confuse scrollIntoView's choice of\n // scrollable parent.\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container || messages.length === 0) return;\n if (hasInitiallyScrolledRef.current) return;\n\n hasInitiallyScrolledRef.current = true;\n prevMessageCount.current = messages.length;\n\n const firstUnread = messages.find(\n (m) =>\n m.type !== 'system' &&\n m.senderId !== currentUserId &&\n !(m.readBy ?? []).includes(currentUserId)\n );\n\n if (firstUnread) {\n const el = container.querySelector(\n `[data-message-id=\"${firstUnread.id}\"]`\n ) as HTMLElement | null;\n if (el) {\n // Compute the element's offset within the scrollable container\n // via getBoundingClientRect so we don't depend on offsetParent\n // chains. Pad 16px so the day divider above the message stays\n // visible.\n const containerRect = container.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const offset = elRect.top - containerRect.top + container.scrollTop;\n container.scrollTop = Math.max(0, offset - 16);\n return;\n }\n }\n\n container.scrollTop = container.scrollHeight;\n }, [messages, currentUserId]);\n\n // Subsequent message arrivals: smooth-scroll only when it's the\n // user's own send, or they were already near the bottom. Don't yank\n // them away from older messages they're reading.\n useEffect(() => {\n if (!hasInitiallyScrolledRef.current) return;\n if (messages.length > prevMessageCount.current) {\n const lastMessage = messages[messages.length - 1];\n const isOwnMessage = lastMessage?.senderId === currentUserId;\n if (isOwnMessage || isNearBottom(containerRef.current)) {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }\n }\n prevMessageCount.current = messages.length;\n }, [messages, currentUserId]);\n\n // Intersection observer for marking messages as read\n useEffect(() => {\n if (!onMessageVisible || !containerRef.current) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const messageId = (entry.target as HTMLElement).dataset.messageId;\n if (messageId) onMessageVisible(messageId);\n }\n });\n },\n { root: containerRef.current, threshold: 0.5 }\n );\n\n const messageElements = containerRef.current.querySelectorAll('[data-message-id]');\n messageElements.forEach((el) => observer.observe(el));\n\n return () => observer.disconnect();\n }, [messages, onMessageVisible]);\n\n // Scroll-to-top detection for loading more messages\n const handleScroll = useCallback(() => {\n if (!containerRef.current || !hasMore || isLoading) return;\n\n if (containerRef.current.scrollTop < 50) {\n onLoadMore();\n }\n }, [hasMore, isLoading, onLoadMore]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={styles.container}\n onScroll={handleScroll}\n >\n {/* Load more indicator */}\n {isLoading && messages.length > 0 && (\n <div style={styles.loadingMore}>\n <Spinner size={14} />\n <span>Loading earlier messages…</span>\n </div>\n )}\n\n {hasMore && !isLoading && messages.length > 0 && (\n <button onClick={onLoadMore} style={styles.loadMoreButton} type=\"button\">\n Load earlier messages\n </button>\n )}\n\n {/* Empty state */}\n {messages.length === 0 && !isLoading && (\n <div style={styles.empty}>\n <ChatIllustration size={104} />\n <p style={styles.emptyTitle}>No messages yet</p>\n <p style={styles.emptySubtitle}>\n Start the conversation β€” everyone on this case will see what you write.\n </p>\n </div>\n )}\n\n {/* First-load spinner (no messages, still loading) */}\n {messages.length === 0 && isLoading && (\n <div style={styles.firstLoad}>\n <Spinner size={20} />\n </div>\n )}\n\n {/* Message list β€” day dividers inserted when the bucket key changes.\n Messages arrive sorted oldest β†’ newest. We carry the last *valid*\n bucket forward so a single bad insertedAt (yielding \"\") doesn't\n break the divider chain for surrounding messages. */}\n {(() => {\n let lastValidBucket: string | null = null;\n return messages.map((message) => {\n const currentBucket = dayBucketKey(message.insertedAt);\n const showDivider = !!currentBucket && currentBucket !== lastValidBucket;\n if (currentBucket) lastValidBucket = currentBucket;\n\n return (\n <React.Fragment key={message.id}>\n {showDivider && (\n <div style={styles.dayDivider} role=\"separator\" aria-label=\"Date\">\n <span style={styles.dayHr} aria-hidden=\"true\" />\n <span style={styles.dayLabel}>{formatDayDivider(message.insertedAt)}</span>\n <span style={styles.dayHr} aria-hidden=\"true\" />\n </div>\n )}\n <div data-message-id={message.id} data-natoe-message-bubble style={styles.bubbleSlot}>\n <MessageBubble\n message={message}\n isOwn={message.senderId === currentUserId}\n participants={participants}\n currentUserId={currentUserId}\n showSeenBy={showSeenBy}\n onDeepLinkClick={onDeepLinkClick}\n onReply={onReply}\n onPin={onPin}\n onUnpin={onUnpin}\n onCopy={onCopy}\n onRetry={onRetry}\n pinDisabled={pinDisabled}\n />\n </div>\n </React.Fragment>\n );\n });\n })()}\n\n {/* Typing indicators */}\n {typingUsers.length > 0 && (\n <div style={styles.typingIndicator}>\n {typingUsers.map((t) => t.userName ?? 'Someone').join(', ')}\n {typingUsers.length === 1 ? ' is ' : ' are '}typing...\n </div>\n )}\n\n <div ref={bottomRef} />\n </div>\n );\n});\n\nfunction isNearBottom(container: HTMLDivElement | null): boolean {\n if (!container) return true;\n const threshold = 150;\n return container.scrollHeight - container.scrollTop - container.clientHeight < threshold;\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n flex: 1,\n overflowY: 'auto',\n paddingTop: SPACE.S3,\n paddingBottom: SPACE.S2,\n },\n loadingMore: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE.S2,\n padding: SPACE.S3,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n firstLoad: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S4}`,\n },\n loadMoreButton: {\n display: 'block',\n margin: `0 auto ${SPACE.S3}`,\n minHeight: '36px',\n padding: `${SPACE.S2} ${SPACE.S5}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral700,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.pill,\n cursor: 'pointer',\n },\n empty: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S4}`,\n color: COLOR.neutral500,\n },\n emptyTitle: {\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n margin: `${SPACE.S3} 0 ${SPACE.S1}`,\n },\n emptySubtitle: {\n fontSize: FONT_SIZE.sm,\n margin: 0,\n maxWidth: '280px',\n lineHeight: LINE_HEIGHT.normal,\n textAlign: 'center' as const,\n },\n typingIndicator: {\n padding: `${SPACE.S1} ${SPACE.S4} ${SPACE.S2}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n fontStyle: 'italic',\n },\n dayDivider: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n margin: `${SPACE.S4} 0 ${SPACE.S3}`,\n position: 'sticky',\n top: SPACE.S1,\n zIndex: Z_INDEX.sticky,\n pointerEvents: 'none',\n },\n dayHr: {\n flex: 1,\n height: '1px',\n backgroundColor: COLOR.neutral200,\n },\n dayLabel: {\n flexShrink: 0,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n // Subtle pill background so the label is readable when it overlays\n // bubbles passing under it during sticky scroll. Without this the\n // hairlines visually run through the text on tinted backgrounds.\n padding: `2px ${SPACE.S2}`,\n backgroundColor: COLOR.white,\n borderRadius: RADIUS.sm,\n },\n bubbleSlot: {\n animation: 'natoe-colab-message-in 180ms ease-out',\n },\n};\n","import React from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface ReplyPreviewProps {\n /** The message being replied to */\n message: Message;\n /** Called when user cancels the reply */\n onCancel: () => void;\n className?: string;\n}\n\n/**\n * Shown above the MessageInput when the user is composing a reply.\n * Displays the quoted message with a cancel button.\n */\nexport function ReplyPreview({ message, onCancel, className }: ReplyPreviewProps) {\n const preview = renderQuotedPreview(message);\n\n return (\n <div className={className} style={styles.container}>\n <div style={styles.bar} />\n <div style={styles.content}>\n <div style={styles.senderLine}>\n <span style={styles.senderIcon}>↩</span>\n <span style={styles.senderName}>Replying to {message.senderName}</span>\n </div>\n <div style={styles.preview}>{preview}</div>\n </div>\n <button onClick={onCancel} style={styles.cancelButton} title=\"Cancel reply\" type=\"button\">\n βœ•\n </button>\n </div>\n );\n}\n\nfunction renderQuotedPreview(message: Message): string {\n switch (message.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default: {\n const body = message.body || '';\n return body.length > 120 ? `${body.slice(0, 120)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'stretch',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S3}`,\n backgroundColor: COLOR.neutral50,\n borderTop: `1px solid ${COLOR.neutral200}`,\n },\n bar: {\n width: '3px',\n backgroundColor: COLOR.primary,\n borderRadius: '2px',\n flexShrink: 0,\n },\n content: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n minWidth: 0,\n },\n senderLine: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n },\n senderIcon: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n },\n senderName: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n },\n preview: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n cancelButton: {\n alignSelf: 'center',\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n flexShrink: 0,\n },\n};\n","import React from 'react';\n\nexport function AttachIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function SendIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n );\n}\n","import React from 'react';\n\nexport function CloseIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <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\" />\n </svg>\n );\n}\n","import React, { useState, useRef, useCallback, useEffect } from 'react';\n// MIC DISABLED β€” voice messaging temporarily removed. Imports kept for easy re-enable.\n// import { useAudioRecorder } from '../hooks/useAudioRecorder';\n// import { MicIcon } from './icons/MicIcon';\nimport { ReplyPreview } from './ReplyPreview';\nimport { AttachIcon } from './icons/AttachIcon';\nimport { SendIcon } from './icons/SendIcon';\nimport { CloseIcon } from './icons/CloseIcon';\nimport { MAX_FILE_SIZE, SUPPORTED_IMAGE_TYPES } from '../core/constants';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SIZE,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface MessageInputProps {\n onSendText: (body: string) => Promise<void>;\n /** @deprecated MIC DISABLED β€” kept in the prop signature for backward compat. */\n onSendAudio?: (blob: Blob, duration: number) => Promise<void>;\n onSendFile: (file: File) => Promise<void>;\n onTyping: (isTyping: boolean) => void;\n /** When set, shows a ReplyPreview above the input */\n replyTo?: Message | null;\n /** Called when user cancels the reply */\n onCancelReply?: () => void;\n disabled?: boolean;\n placeholder?: string;\n className?: string;\n}\n\nexport function MessageInput({\n onSendText,\n // MIC DISABLED β€” onSendAudio still accepted but unused.\n // onSendAudio,\n onSendFile,\n onTyping,\n replyTo,\n onCancelReply,\n disabled = false,\n placeholder = 'Type a message...',\n className,\n}: MessageInputProps) {\n const [text, setText] = useState('');\n const [isSending, setIsSending] = useState(false);\n const [isUploading, setIsUploading] = useState(false);\n const [fileError, setFileError] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isTypingRef = useRef(false);\n // Synchronous guard β€” useState's async update can't block a second click\n // that lands before React re-renders. The ref flips immediately.\n const sendingRef = useRef(false);\n\n // MIC DISABLED β€” voice recorder hook is not invoked. Restore by uncommenting\n // the original destructure below (and the import at the top of the file).\n // const { isRecording, duration, start: startRecording, stop: stopRecording, cancel: cancelRecording, isSupported: micSupported, error: micError } = useAudioRecorder();\n\n // Rising-edge only β€” fire once when the user starts typing, then a single\n // \"stopped\" event after 2s of idle. Previously this called onTyping(true)\n // on EVERY keystroke, flooding the socket with redundant events.\n const handleTyping = useCallback(() => {\n if (!isTypingRef.current) {\n isTypingRef.current = true;\n onTyping(true);\n }\n\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n typingTimeoutRef.current = setTimeout(() => {\n isTypingRef.current = false;\n onTyping(false);\n }, 2000);\n }, [onTyping]);\n\n useEffect(() => {\n return () => {\n if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current);\n };\n }, []);\n\n const handleSendText = useCallback(async () => {\n const trimmed = text.trim();\n if (!trimmed || sendingRef.current) return;\n\n sendingRef.current = true;\n setIsSending(true);\n if (isTypingRef.current) {\n isTypingRef.current = false;\n onTyping(false);\n }\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n typingTimeoutRef.current = null;\n }\n\n try {\n await onSendText(trimmed);\n setText('');\n } finally {\n sendingRef.current = false;\n setIsSending(false);\n }\n }, [text, onSendText, onTyping]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSendText();\n }\n },\n [handleSendText]\n );\n\n // MIC DISABLED β€” audio stop handler unused. Restore alongside useAudioRecorder.\n // const handleAudioStop = useCallback(async () => {\n // const result = await stopRecording();\n // if (result) {\n // setIsSending(true);\n // try {\n // await onSendAudio(result.blob, result.duration);\n // } finally {\n // setIsSending(false);\n // }\n // }\n // }, [stopRecording, onSendAudio]);\n\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n setFileError(null);\n\n if (file.size > MAX_FILE_SIZE) {\n setFileError(`File too large. Maximum size is ${MAX_FILE_SIZE / (1024 * 1024)}MB.`);\n return;\n }\n\n setIsSending(true);\n setIsUploading(true);\n try {\n await onSendFile(file);\n } finally {\n setIsSending(false);\n setIsUploading(false);\n // Reset file input\n if (fileInputRef.current) fileInputRef.current.value = '';\n }\n },\n [onSendFile]\n );\n\n return (\n <div className={className} style={styles.container}>\n {/* Reply preview */}\n {replyTo && onCancelReply && (\n <ReplyPreview message={replyTo} onCancel={onCancelReply} />\n )}\n\n {/* Upload progress banner */}\n {isUploading && (\n <div style={styles.uploadBanner}>\n <span style={styles.uploadSpinner} />\n Uploading file…\n </div>\n )}\n\n {/* Error messages */}\n {fileError && (\n <div style={styles.error} role=\"alert\">\n <span style={styles.errorText}>{fileError}</span>\n <button\n type=\"button\"\n onClick={() => setFileError(null)}\n aria-label=\"Dismiss error\"\n style={styles.errorDismiss}\n >\n <CloseIcon size={16} />\n </button>\n </div>\n )}\n\n {/* MIC DISABLED β€” recording bar and mic button removed.\n Original blocks kept here for easy re-enable:\n\n {isRecording ? (\n <div style={styles.recordingBar}>\n <div style={styles.recordingIndicator}>\n <span style={styles.recordingDot} />\n Recording {formatDuration(duration)}\n </div>\n <div style={styles.recordingActions}>\n <button onClick={cancelRecording} style={styles.cancelButton} type=\"button\">Cancel</button>\n <button onClick={handleAudioStop} style={styles.stopButton} type=\"button\">Send</button>\n </div>\n </div>\n ) : (\n ...input bar with mic button...\n )}\n */}\n <div style={styles.inputBar}>\n {/* MIC DISABLED β€” mic button hidden.\n {micSupported && (\n <button onClick={startRecording} disabled={disabled || isSending} style={styles.iconButton} title=\"Record voice message\" type=\"button\">\n <MicIcon size={20} color=\"#374151\" />\n </button>\n )}\n */}\n\n {/* File attach β€” 48px square tile, prototype-style */}\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={disabled || isSending}\n style={styles.attachButton}\n aria-label=\"Attach file\"\n title=\"Attach file\"\n type=\"button\"\n >\n <AttachIcon size={22} color={COLOR.neutral700} />\n </button>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n onChange={handleFileSelect}\n style={{ display: 'none' }}\n accept={[\n ...SUPPORTED_IMAGE_TYPES,\n 'application/pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.csv',\n '.txt',\n '.heic',\n '.heif',\n ].join(',')}\n />\n\n {/* Text input */}\n <textarea\n value={text}\n onChange={(e) => {\n setText(e.target.value);\n handleTyping();\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || isSending}\n rows={1}\n style={styles.textarea}\n />\n\n {/* Send β€” icon + \"Send\" label, prototype-style pill */}\n <button\n onClick={handleSendText}\n disabled={disabled || isSending || !text.trim()}\n aria-label=\"Send message\"\n title=\"Send message\"\n style={{\n ...styles.sendButton,\n opacity: text.trim() ? 1 : 0.5,\n }}\n type=\"button\"\n >\n <SendIcon size={20} color={COLOR.white} />\n <span style={styles.sendLabel}>Send</span>\n </button>\n </div>\n </div>\n );\n}\n\n// MIC DISABLED β€” formatDuration was only used by the recording UI.\n// Kept here for easy restore when mic is re-enabled.\n// function formatDuration(seconds: number): string {\n// const m = Math.floor(seconds / 60);\n// const s = seconds % 60;\n// return `${m}:${s.toString().padStart(2, '0')}`;\n// }\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n borderTop: `1px solid ${COLOR.neutral200}`,\n backgroundColor: COLOR.white,\n },\n uploadBanner: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: COLOR.neutral50,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n uploadSpinner: {\n display: 'inline-block',\n width: '12px',\n height: '12px',\n border: `2px solid ${COLOR.neutral300}`,\n borderTopColor: COLOR.primary,\n borderRadius: RADIUS.full,\n animation: 'natoe-colab-spin 0.7s linear infinite',\n flexShrink: 0,\n },\n error: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S3} ${SPACE.S2} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.dangerFg,\n backgroundColor: COLOR.dangerBg,\n borderTop: `1px solid ${COLOR.dangerBorder}`,\n },\n errorText: {\n flex: 1,\n minWidth: 0,\n },\n errorDismiss: {\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n color: COLOR.dangerFg,\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n flexShrink: 0,\n },\n inputBar: {\n display: 'flex',\n alignItems: 'flex-end',\n gap: '10px',\n padding: `${SPACE.S3} ${SPACE.S4} 14px`,\n },\n // 48px square tile with a 14px corner radius β€” visually grounds the\n // attach affordance as part of the composer chrome rather than a stray\n // round icon button.\n attachButton: {\n width: '48px',\n height: '48px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n color: COLOR.neutral700,\n transition: 'background-color 120ms ease, color 120ms ease, border-color 120ms ease',\n },\n iconButton: {\n width: SIZE.controlPrimary,\n height: SIZE.controlPrimary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n textarea: {\n flex: 1,\n minHeight: '48px',\n maxHeight: '140px',\n padding: '13px 16px',\n fontSize: FONT_SIZE.md,\n lineHeight: LINE_HEIGHT.normal,\n color: COLOR.neutral900,\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n resize: 'none',\n outline: 'none',\n fontFamily: 'inherit',\n transition: 'background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease',\n },\n // Pill-shaped send: icon + \"Send\" label. Always labelled (never icon-\n // only) so the affordance is obvious to first-time users.\n sendButton: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '6px',\n minWidth: '48px',\n height: '48px',\n padding: `0 ${SPACE.S4}`,\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n border: 'none',\n borderRadius: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n fontFamily: 'inherit',\n fontSize: '15px',\n fontWeight: FONT_WEIGHT.semibold,\n transition: 'opacity 120ms ease, background-color 120ms ease',\n },\n sendLabel: {\n lineHeight: 1,\n },\n recordingBar: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: `${SPACE.S3} ${SPACE.S4}`,\n backgroundColor: COLOR.dangerBg,\n },\n recordingIndicator: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n fontWeight: FONT_WEIGHT.medium,\n },\n recordingDot: {\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.danger,\n animation: 'pulse 1.5s infinite',\n },\n recordingActions: {\n display: 'flex',\n gap: SPACE.S2,\n },\n cancelButton: {\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n stopButton: {\n padding: `${SPACE.S1} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n};\n","import React from 'react';\nimport { COLOR, FONT_SIZE, FONT_WEIGHT, RADIUS, SPACE } from '../core/theme';\nimport type { Participant, UserRole } from '../core/types';\n\ninterface ParticipantsListProps {\n participants: Participant[];\n currentUserId: string;\n isAdmin: boolean;\n onRemoveUser: (userId: string) => Promise<void>;\n className?: string;\n}\n\nexport function ParticipantsList({\n participants,\n currentUserId,\n isAdmin,\n onRemoveUser,\n className,\n}: ParticipantsListProps) {\n return (\n <div className={className} style={styles.list}>\n {participants.map((participant) => (\n <div key={participant.userId} style={styles.item}>\n {/* Avatar */}\n <div style={styles.avatar}>\n {participant.avatar ? (\n <img src={participant.avatar} alt=\"\" style={styles.avatarImg} />\n ) : (\n <span style={styles.avatarFallback}>\n {(participant.userName ?? '?').charAt(0).toUpperCase()}\n </span>\n )}\n {/* Online indicator */}\n <span\n style={{\n ...styles.statusDot,\n backgroundColor: participant.isOnline ? COLOR.success : COLOR.neutral300,\n }}\n />\n </div>\n\n {/* Info */}\n <div style={styles.info}>\n <span style={styles.name}>\n {participant.userName ?? fallbackName(participant.userRole)}\n {participant.userId === currentUserId && (\n <span style={styles.youBadge}> (you)</span>\n )}\n </span>\n <RoleBadge role={participant.userRole} />\n </div>\n\n {/* Remove button (admin only, can't remove self) */}\n {isAdmin && participant.userId !== currentUserId && (\n <button\n onClick={() => onRemoveUser(participant.userId)}\n style={styles.removeButton}\n title={`Remove ${participant.userName ?? fallbackName(participant.userRole)}`}\n type=\"button\"\n >\n βœ•\n </button>\n )}\n </div>\n ))}\n </div>\n );\n}\n\nfunction fallbackName(role: UserRole): string {\n switch (role) {\n case 'lab':\n return 'Imaging Center';\n case 'radiologist':\n return 'Radiologist';\n case 'physician':\n return 'Physician';\n case 'admin':\n return 'Natoe Admin';\n default:\n return 'User';\n }\n}\n\nfunction RoleBadge({ role }: { role: UserRole }) {\n // Cool-only palette β€” matches MessageBubble.roleColor() and CollabInline.\n // No greens / reds / purples; roles stay distinguishable via tone\n // (indigo / brand-blue / sky / slate) within the blue family.\n const colors: Record<UserRole, { bg: string; text: string }> = {\n radiologist: { bg: '#eef2ff', text: '#4f46e5' }, // indigo\n lab: { bg: '#eff6ff', text: '#2563eb' }, // brand blue\n physician: { bg: '#e0f2fe', text: '#0284c7' }, // sky\n admin: { bg: '#f1f5f9', text: '#64748b' }, // slate\n };\n\n const color = colors[role];\n\n return (\n <span style={{ ...styles.roleBadge, backgroundColor: color.bg, color: color.text }}>\n {role}\n </span>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n list: {\n display: 'flex',\n flexDirection: 'column',\n },\n item: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n padding: `${SPACE.S2} 0`,\n borderBottom: `1px solid ${COLOR.neutral50}`,\n },\n avatar: {\n position: 'relative',\n width: '32px',\n height: '32px',\n flexShrink: 0,\n },\n avatarImg: {\n width: '32px',\n height: '32px',\n borderRadius: RADIUS.full,\n objectFit: 'cover' as const,\n },\n avatarFallback: {\n width: '32px',\n height: '32px',\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.neutral200,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n },\n statusDot: {\n position: 'absolute' as const,\n bottom: '0',\n right: '0',\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n border: `2px solid ${COLOR.white}`,\n },\n info: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n flex: 1,\n minWidth: 0,\n },\n name: {\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n youBadge: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.regular,\n color: COLOR.neutral400,\n },\n roleBadge: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n padding: `2px ${SPACE.S2}`,\n borderRadius: RADIUS.sm,\n whiteSpace: 'nowrap' as const,\n },\n removeButton: {\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral400,\n flexShrink: 0,\n },\n};\n","import React, { useState } from 'react';\nimport { ParticipantsList } from './ParticipantsList';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Participant, InviteUserPayload, UserRole, CollabError } from '../core/types';\n\ninterface ChannelSettingsProps {\n conversationId: string;\n channelName: string;\n channelPicture?: string;\n participants: Participant[];\n currentUserId: string;\n isAdmin: boolean;\n isUpdating: boolean;\n error: CollabError | null;\n onUpdateChannel: (payload: { name?: string; picture?: string }) => Promise<void>;\n onInviteUser: (payload: InviteUserPayload) => Promise<void>;\n onRemoveUser: (userId: string) => Promise<void>;\n onLeaveChannel: () => Promise<void>;\n onDeleteChannel: () => Promise<void>;\n onClose: () => void;\n className?: string;\n}\n\nexport function ChannelSettings({\n channelName,\n participants,\n currentUserId,\n isAdmin,\n isUpdating,\n error,\n onUpdateChannel,\n onInviteUser,\n onRemoveUser,\n onLeaveChannel,\n onDeleteChannel,\n onClose,\n className,\n}: ChannelSettingsProps) {\n const [editingName, setEditingName] = useState(false);\n const [nameValue, setNameValue] = useState(channelName);\n const [showInvite, setShowInvite] = useState(false);\n const [inviteId, setInviteId] = useState('');\n const [inviteName, setInviteName] = useState('');\n const [inviteRole, setInviteRole] = useState<UserRole>('radiologist');\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n const handleSaveName = async () => {\n if (nameValue.trim() && nameValue !== channelName) {\n await onUpdateChannel({ name: nameValue.trim() });\n }\n setEditingName(false);\n };\n\n const handleInvite = async () => {\n if (!inviteId.trim() || !inviteName.trim()) return;\n await onInviteUser({\n userId: inviteId.trim(),\n userName: inviteName.trim(),\n userRole: inviteRole,\n });\n setInviteId('');\n setInviteName('');\n setShowInvite(false);\n };\n\n const handleDelete = async () => {\n if (!confirmDelete) {\n setConfirmDelete(true);\n return;\n }\n await onDeleteChannel();\n };\n\n return (\n <div className={className} style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <h3 style={styles.title}>Channel Settings</h3>\n <button onClick={onClose} style={styles.closeButton} type=\"button\">\n βœ•\n </button>\n </div>\n\n {/* Error */}\n {error && (\n <div style={styles.error}>{error.message}</div>\n )}\n\n {/* Channel name */}\n <div style={styles.section}>\n <label style={styles.label}>Channel Name</label>\n {editingName ? (\n <div style={styles.editRow}>\n <input\n value={nameValue}\n onChange={(e) => setNameValue(e.target.value)}\n style={styles.input}\n autoFocus\n />\n <button onClick={handleSaveName} disabled={isUpdating} style={styles.saveButton} type=\"button\">\n Save\n </button>\n <button onClick={() => setEditingName(false)} style={styles.cancelButton} type=\"button\">\n Cancel\n </button>\n </div>\n ) : (\n <div style={styles.editRow}>\n <span style={styles.channelName}>{channelName}</span>\n <button onClick={() => setEditingName(true)} style={styles.editButton} type=\"button\">\n Edit\n </button>\n </div>\n )}\n </div>\n\n {/* Participants */}\n <div style={styles.section}>\n <div style={styles.sectionHeader}>\n <label style={styles.label}>Participants ({participants.length})</label>\n <button onClick={() => setShowInvite(!showInvite)} style={styles.addButton} type=\"button\">\n + Add\n </button>\n </div>\n\n {/* Invite form */}\n {showInvite && (\n <div style={styles.inviteForm}>\n <input\n value={inviteId}\n onChange={(e) => setInviteId(e.target.value)}\n placeholder=\"User ID\"\n style={styles.input}\n />\n <input\n value={inviteName}\n onChange={(e) => setInviteName(e.target.value)}\n placeholder=\"User Name\"\n style={styles.input}\n />\n <select\n value={inviteRole}\n onChange={(e) => setInviteRole(e.target.value as UserRole)}\n style={styles.input}\n >\n <option value=\"radiologist\">Radiologist</option>\n <option value=\"lab\">Lab</option>\n <option value=\"physician\">Physician</option>\n <option value=\"admin\">Admin</option>\n </select>\n <div style={styles.inviteActions}>\n <button onClick={handleInvite} disabled={isUpdating} style={styles.saveButton} type=\"button\">\n Invite\n </button>\n <button onClick={() => setShowInvite(false)} style={styles.cancelButton} type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n )}\n\n <ParticipantsList\n participants={participants}\n currentUserId={currentUserId}\n isAdmin={isAdmin}\n onRemoveUser={onRemoveUser}\n />\n </div>\n\n {/* Actions */}\n <div style={styles.dangerZone}>\n <button onClick={onLeaveChannel} disabled={isUpdating} style={styles.leaveButton} type=\"button\">\n Leave Channel\n </button>\n\n {isAdmin && (\n <button\n onClick={handleDelete}\n disabled={isUpdating}\n style={confirmDelete ? styles.confirmDeleteButton : styles.deleteButton}\n type=\"button\"\n >\n {confirmDelete ? 'Confirm Delete' : 'Delete Channel'}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n },\n header: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: `${SPACE.S3} ${SPACE.S4}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n },\n title: {\n margin: 0,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n },\n closeButton: {\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n error: {\n padding: `${SPACE.S2} ${SPACE.S4}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n },\n section: {\n padding: SPACE.S4,\n borderBottom: `1px solid ${COLOR.neutral100}`,\n },\n sectionHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: SPACE.S2,\n },\n label: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral500,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n },\n channelName: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral900,\n },\n editRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n marginTop: SPACE.S2,\n },\n input: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n outline: 'none',\n width: '100%',\n },\n editButton: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n },\n saveButton: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n whiteSpace: 'nowrap' as const,\n },\n cancelButton: {\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n whiteSpace: 'nowrap' as const,\n },\n addButton: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.primary,\n backgroundColor: COLOR.primaryBg,\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n },\n inviteForm: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: SPACE.S2,\n padding: SPACE.S3,\n marginBottom: SPACE.S3,\n backgroundColor: COLOR.neutral50,\n borderRadius: RADIUS.md,\n },\n inviteActions: {\n display: 'flex',\n gap: SPACE.S2,\n },\n dangerZone: {\n padding: SPACE.S4,\n marginTop: 'auto',\n display: 'flex',\n flexDirection: 'column' as const,\n gap: SPACE.S2,\n },\n leaveButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.warning,\n backgroundColor: '#fffbeb',\n border: '1px solid #fde68a',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n deleteButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n confirmDeleteButton: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n },\n};\n","import React, { useState } from 'react';\nimport { PinIcon } from './icons/PinIcon';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message } from '../core/types';\n\ninterface PinnedMessagesBarProps {\n pinnedMessages: Message[];\n /** Clicking a pinned message scrolls to it in the thread */\n onJumpTo: (messageId: string) => void;\n /** Called when user unpins a message */\n onUnpin: (messageId: string) => void;\n className?: string;\n}\n\n/**\n * Horizontal strip at the top of the thread showing pinned messages (max 3).\n * Cycles through them on click if more than one.\n */\nexport function PinnedMessagesBar({\n pinnedMessages,\n onJumpTo,\n onUnpin,\n className,\n}: PinnedMessagesBarProps) {\n const [index, setIndex] = useState(0);\n\n if (pinnedMessages.length === 0) return null;\n\n const safeIndex = Math.min(index, pinnedMessages.length - 1);\n const current = pinnedMessages[safeIndex];\n const preview = renderPinPreview(current);\n\n const handleClick = () => {\n onJumpTo(current.id);\n if (pinnedMessages.length > 1) {\n setIndex((prev) => (prev + 1) % pinnedMessages.length);\n }\n };\n\n return (\n <div className={className} style={styles.container}>\n <div style={styles.indicator}>\n <PinIcon size={14} color={COLOR.primary} />\n {pinnedMessages.length > 1 && (\n <div style={styles.segments}>\n {pinnedMessages.map((_, i) => (\n <span\n key={i}\n style={{\n ...styles.segment,\n backgroundColor: i === safeIndex ? COLOR.primary : COLOR.neutral300,\n }}\n />\n ))}\n </div>\n )}\n </div>\n\n <button\n onClick={handleClick}\n style={styles.contentButton}\n type=\"button\"\n title=\"Click to jump to message\"\n >\n <div style={styles.label}>\n Pinned {pinnedMessages.length > 1 ? `(${safeIndex + 1}/${pinnedMessages.length})` : ''}\n </div>\n <div style={styles.preview}>\n <span style={styles.sender}>{current.senderName}:</span> {preview}\n </div>\n </button>\n\n <button\n onClick={(e) => {\n e.stopPropagation();\n onUnpin(current.id);\n }}\n style={styles.unpinButton}\n title=\"Unpin this message\"\n type=\"button\"\n >\n βœ•\n </button>\n </div>\n );\n}\n\nfunction renderPinPreview(message: Message): string {\n switch (message.type) {\n case 'audio':\n return '🎀 Voice message';\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default: {\n const body = message.body || '';\n return body.length > 100 ? `${body.slice(0, 100)}…` : body;\n }\n }\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S3}`,\n backgroundColor: COLOR.primaryBg,\n borderBottom: `1px solid ${COLOR.primaryBg}`,\n },\n indicator: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S1,\n flexShrink: 0,\n },\n segments: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n },\n segment: {\n width: '3px',\n height: '6px',\n borderRadius: '1px',\n },\n contentButton: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n padding: '2px 0',\n backgroundColor: 'transparent',\n border: 'none',\n textAlign: 'left',\n cursor: 'pointer',\n minWidth: 0,\n overflow: 'hidden',\n },\n label: {\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.primary,\n },\n preview: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral700,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n sender: {\n fontWeight: FONT_WEIGHT.semibold,\n },\n unpinButton: {\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.sm,\n cursor: 'pointer',\n fontSize: FONT_SIZE.xs,\n flexShrink: 0,\n },\n};\n","import React, { useEffect } from 'react';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SHADOW,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\n\nexport interface ToastState {\n message: string;\n actionLabel?: string;\n onAction?: () => void;\n}\n\ninterface ToastProps {\n toast: ToastState | null;\n onDismiss: () => void;\n /** Auto-dismiss duration in ms. Default 4000. */\n durationMs?: number;\n}\n\n/**\n * Brief in-app confirmation (Pinned / Unpinned / Copied, etc.) with an\n * optional action button. Auto-dismisses after `durationMs`. Anchored to\n * the bottom of its containing positioned ancestor.\n */\nexport function Toast({ toast, onDismiss, durationMs = 4000 }: ToastProps) {\n useEffect(() => {\n if (!toast) return;\n const timer = setTimeout(onDismiss, durationMs);\n return () => clearTimeout(timer);\n }, [toast, onDismiss, durationMs]);\n\n if (!toast) return null;\n\n return (\n <div style={styles.container} role=\"status\" aria-live=\"polite\">\n <span style={styles.message}>{toast.message}</span>\n {toast.actionLabel && toast.onAction && (\n <button\n type=\"button\"\n onClick={() => {\n toast.onAction?.();\n onDismiss();\n }}\n style={styles.action}\n >\n {toast.actionLabel}\n </button>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n position: 'absolute',\n bottom: '76px',\n left: '50%',\n transform: 'translateX(-50%)',\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S3,\n padding: `${SPACE.S3} ${SPACE.S4}`,\n backgroundColor: COLOR.slate800,\n color: COLOR.white,\n borderRadius: RADIUS.md,\n boxShadow: SHADOW.toast,\n fontSize: FONT_SIZE.sm,\n maxWidth: '90%',\n zIndex: Z_INDEX.toast,\n },\n message: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n action: {\n background: 'transparent',\n border: 'none',\n color: COLOR.primaryBg,\n fontWeight: FONT_WEIGHT.semibold,\n fontSize: FONT_SIZE.sm,\n cursor: 'pointer',\n padding: `${SPACE.S1} ${SPACE.S2}`,\n textTransform: 'uppercase',\n letterSpacing: '0.4px',\n },\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport { useConversation } from '../hooks/useConversation';\nimport { useChannelSettings } from '../hooks/useChannelSettings';\nimport { useDeepLinks } from '../hooks/useDeepLinks';\nimport { useCollab } from '../context/CollabProvider';\nimport { PatientHeader } from './PatientHeader';\nimport { MessageList, type MessageListHandle } from './MessageList';\nimport { MessageInput } from './MessageInput';\nimport { ChannelSettings } from './ChannelSettings';\nimport { PinnedMessagesBar } from './PinnedMessagesBar';\nimport { Toast, type ToastState } from './Toast';\nimport { MAX_PINNED_MESSAGES } from '../core/constants';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Conversation, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\n/**\n * Override values for the themeable CSS variables when the panel is in\n * dark mode. Light mode just falls back to THEME_DEFAULTS.\n *\n * Strategy: invert the neutrals around the spectrum (light bg/border tokens\n * become dark; muted-text tokens become light) and dim the primary chip\n * surface so it doesn't glow on a black background. Brand primary and\n * danger/role colors stay the same β€” they read fine on dark surfaces.\n */\nconst DARK_THEME_OVERRIDES: React.CSSProperties = {\n ['--natoe-colab-white' as never]: '#0b0b0c',\n ['--natoe-colab-neutral-50' as never]: '#18181c',\n ['--natoe-colab-neutral-100' as never]: '#1f1f23',\n ['--natoe-colab-neutral-200' as never]: '#2a2a2e',\n ['--natoe-colab-neutral-300' as never]: '#3f3f44',\n ['--natoe-colab-neutral-400' as never]: '#6b7280',\n ['--natoe-colab-neutral-500' as never]: '#9ca3af',\n ['--natoe-colab-neutral-600' as never]: '#cbd5e1',\n ['--natoe-colab-neutral-700' as never]: '#e5e7eb',\n ['--natoe-colab-neutral-800' as never]: '#f3f4f6',\n ['--natoe-colab-neutral-900' as never]: '#ffffff',\n ['--natoe-colab-primary-bg' as never]: 'rgba(37, 99, 235, 0.18)',\n};\n\ninterface CollabPanelProps {\n /** Order ID β€” one conversation per study */\n orderId: string;\n /** Patient/study data displayed in the header */\n patientData: PatientData;\n /** Participant user IDs β€” only used when creating a brand-new conversation */\n participantIds?: string[];\n /** Show \"seen by\" indicator under own messages (default true) */\n showSeenBy?: boolean;\n /**\n * When set, the header renders a back-arrow button (used by CollabInbox in\n * its compact / single-pane layout to return to the conversation list).\n */\n onBack?: () => void;\n /** Hide the patient name row in the header β€” set when a parent already shows it (e.g. CollabPopup title bar) */\n hidePatientName?: boolean;\n /**\n * Notified whenever the underlying conversation state changes (initial\n * preview load, create, channel deletion). Lets a parent like CollabPopup\n * render its title bar from the authoritative conversation.name instead of\n * relying on potentially-incomplete patientData.\n */\n onConversationChange?: (conversation: Conversation | null) => void;\n /**\n * Color mode for the entire panel. Default 'light'. 'dark' is meant for\n * embedding inside the viewer's left panel (#000 background) β€” applies\n * dark overrides for the themeable CSS variables on the panel root, so\n * every internal surface (PatientHeader, MessageList, MessageBubble,\n * MessageInput, PinnedMessagesBar, etc.) inherits them via cascade.\n */\n themeMode?: 'light' | 'dark';\n /** Custom class name for the outer container */\n className?: string;\n /** Custom inline styles for the outer container */\n style?: React.CSSProperties;\n}\n\n/**\n * Full collaboration panel: patient header + pinned bar + message thread + input.\n * Supports reply, pin/unpin, and (optionally) seen-by indicators.\n */\nexport function CollabPanel({\n orderId,\n patientData,\n participantIds,\n showSeenBy = true,\n onBack,\n hidePatientName = false,\n onConversationChange,\n themeMode = 'light',\n className,\n style,\n}: CollabPanelProps) {\n const { config } = useCollab();\n const [showSettings, setShowSettings] = useState(false);\n const [toast, setToast] = useState<ToastState | null>(null);\n const messageListRef = useRef<MessageListHandle>(null);\n\n const {\n conversation,\n messages,\n pinnedMessages,\n participants,\n typingUsers,\n isLoading,\n hasMore,\n error,\n replyTo,\n setReplyTo,\n sendMessage,\n retryMessage,\n sendAudioMessage,\n sendFileMessage,\n sendTyping,\n markAsRead,\n loadMoreMessages,\n pinMessage,\n unpinMessage,\n } = useConversation({ orderId, patientData, participantIds });\n\n // Surface conversation state to parents (CollabPopup uses this to render\n // its title bar from the authoritative conversation.name, which is\n // correct even when the host's patientData.labName is missing).\n useEffect(() => {\n onConversationChange?.(conversation);\n }, [conversation, onConversationChange]);\n\n const channelSettings = useChannelSettings({\n conversationId: conversation?.id ?? null,\n });\n\n const { handleDeepLink } = useDeepLinks();\n\n const handleOpenDicom = () => {\n if (patientData.studyId && patientData.storageId && config.onOpenDicom) {\n config.onOpenDicom(patientData.studyId, patientData.storageId);\n }\n };\n\n const handleJumpToMessage = (messageId: string) => {\n messageListRef.current?.scrollToMessage(messageId);\n };\n\n const handleCopy = async (text: string) => {\n try {\n if (navigator.clipboard) {\n await navigator.clipboard.writeText(text);\n setToast({ message: 'Copied to clipboard' });\n }\n } catch {\n // Silent fail β€” clipboard not available\n }\n };\n\n const handlePin = async (messageId: string) => {\n try {\n await pinMessage(messageId);\n setToast({\n message: 'Pinned',\n actionLabel: 'Undo',\n onAction: () => {\n void unpinMessage(messageId);\n },\n });\n } catch {\n setToast({ message: 'Could not pin message' });\n }\n };\n\n const handleUnpin = async (messageId: string) => {\n try {\n await unpinMessage(messageId);\n setToast({ message: 'Unpinned' });\n } catch {\n setToast({ message: 'Could not unpin message' });\n }\n };\n\n const pinDisabled = pinnedMessages.length >= MAX_PINNED_MESSAGES;\n\n // Inline CSS-variable overrides applied at the panel root in dark mode.\n // Every internal surface reads via var(--natoe-colab-*) so the cascade\n // dark-themes them in one place β€” no per-component palette plumbing.\n const containerStyle: React.CSSProperties = {\n ...panelStyles.container,\n ...(themeMode === 'dark' ? DARK_THEME_OVERRIDES : {}),\n ...style,\n };\n\n if (error) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={containerStyle}>\n <div style={panelStyles.errorState}>\n <p style={panelStyles.errorTitle}>Unable to load conversation</p>\n <p style={panelStyles.errorMessage}>{error}</p>\n </div>\n </div>\n );\n }\n\n if (isLoading && !conversation) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={containerStyle}>\n <div style={panelStyles.loadingState}>Loading conversation...</div>\n </div>\n );\n }\n\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={containerStyle}>\n {showSettings && conversation ? (\n <ChannelSettings\n conversationId={conversation.id}\n channelName={conversation.name}\n channelPicture={conversation.picture}\n participants={participants}\n currentUserId={config.userId}\n isAdmin={channelSettings.isAdmin}\n isUpdating={channelSettings.isUpdating}\n error={channelSettings.error}\n onUpdateChannel={channelSettings.updateChannel}\n onInviteUser={channelSettings.inviteUser}\n onRemoveUser={channelSettings.removeUser}\n onLeaveChannel={channelSettings.leaveChannel}\n onDeleteChannel={channelSettings.deleteChannel}\n onClose={() => setShowSettings(false)}\n />\n ) : (\n <>\n <PatientHeader\n patientData={patientData}\n participants={participants}\n onOpenDicom={handleOpenDicom}\n onOpenSettings={() => setShowSettings(true)}\n onBack={onBack}\n hideName={hidePatientName}\n displayName={conversation?.name}\n />\n\n {pinnedMessages.length > 0 && (\n <PinnedMessagesBar\n pinnedMessages={pinnedMessages}\n onJumpTo={handleJumpToMessage}\n onUnpin={handleUnpin}\n />\n )}\n\n <MessageList\n ref={messageListRef}\n messages={messages}\n currentUserId={config.userId}\n participants={participants}\n showSeenBy={showSeenBy}\n typingUsers={typingUsers}\n hasMore={hasMore}\n isLoading={isLoading}\n onLoadMore={loadMoreMessages}\n onDeepLinkClick={handleDeepLink}\n onMessageVisible={markAsRead}\n onReply={setReplyTo}\n onPin={handlePin}\n onUnpin={handleUnpin}\n onCopy={handleCopy}\n onRetry={retryMessage}\n pinDisabled={pinDisabled}\n />\n\n <MessageInput\n onSendText={sendMessage}\n onSendAudio={sendAudioMessage}\n onSendFile={sendFileMessage}\n onTyping={sendTyping}\n replyTo={replyTo}\n onCancelReply={() => setReplyTo(null)}\n />\n </>\n )}\n <Toast toast={toast} onDismiss={() => setToast(null)} />\n </div>\n );\n}\n\nconst panelStyles: Record<string, React.CSSProperties> = {\n container: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n borderRadius: RADIUS.md,\n overflow: 'hidden',\n border: `1px solid ${COLOR.neutral200}`,\n fontFamily: FONT_STACK,\n },\n loadingState: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n errorState: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n padding: SPACE.S6,\n textAlign: 'center',\n },\n errorTitle: {\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n margin: `0 0 ${SPACE.S1}`,\n },\n errorMessage: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n margin: 0,\n },\n};\n","import React from 'react';\n\nexport function MinimizeIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M6 19h12v2H6z\" />\n </svg>\n );\n}\n\nexport function ExpandIcon({ size = 18, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill={color}\n aria-hidden=\"true\"\n >\n <path d=\"M4 4h16v16H4V4zm2 4v10h12V8H6z\" />\n </svg>\n );\n}\n","import React, { useState, useRef, useCallback, useEffect, useId } from 'react';\nimport { CollabPanel } from './CollabPanel';\nimport { buildChannelName, cleanChannelName } from '../core/channelName';\nimport { CloseIcon } from './icons/CloseIcon';\nimport { MinimizeIcon, ExpandIcon } from './icons/MinimizeIcon';\nimport { BackIcon } from './icons/BackIcon';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n Z_INDEX,\n} from '../core/theme';\nimport type { Conversation, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\n// Selector covering everything the focus trap considers focusable. Excludes\n// disabled controls and elements opted out via tabindex=\"-1\".\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\ninterface CollabPopupProps {\n /** Order ID for this conversation */\n orderId: string;\n /** Patient/study data */\n patientData: PatientData;\n /** Participant user IDs β€” only used when creating a brand-new conversation */\n participantIds?: string[];\n /** Whether the popup is open */\n isOpen: boolean;\n /** Close the popup */\n onClose: () => void;\n /** Optional back navigation β€” renders a ← button in the title bar when provided */\n onBack?: () => void;\n /**\n * When provided, the minimize button calls this callback instead of\n * toggling the popup's own shrink-to-titlebar state. Hosts use this\n * to minimize the popup to an external chip / dock. With this set the\n * minimize button always shows the minimize glyph (no expand state),\n * since the host owns the open/minimized lifecycle.\n */\n onMinimize?: () => void;\n /** Initial position (defaults to bottom-right) */\n initialPosition?: { x: number; y: number };\n /** Width of the popup */\n width?: number;\n /** Height of the popup */\n height?: number;\n className?: string;\n}\n\n/**\n * Draggable floating chat popup β€” drop-in replacement for DraggableChatPopup.\n * Renders a CollabPanel inside a movable, resizable container.\n */\nexport function CollabPopup({\n orderId,\n patientData,\n participantIds,\n isOpen,\n onClose,\n onBack,\n onMinimize,\n initialPosition,\n width = 380,\n height = 520,\n className,\n}: CollabPopupProps) {\n // Default spawn: anchored bottom-right but offset vertically by enough\n // to clear a standard FAB (56px) + its 24px margin + visual breathing room\n // so the popup never lands on top of a host-app launcher button.\n const [position, setPosition] = useState(\n initialPosition || {\n x: window.innerWidth - width - 24,\n y: Math.max(24, window.innerHeight - height - 104),\n }\n );\n const [isDragging, setIsDragging] = useState(false);\n const [isMinimized, setIsMinimized] = useState(false);\n // Loaded conversation surfaced by CollabPanel's onConversationChange.\n // Used to render the title bar from the authoritative conversation.name\n // instead of relying on the host's patientData (which may be missing\n // labName when reopened from a stored snapshot that lacks it).\n const [loadedConversation, setLoadedConversation] = useState<Conversation | null>(null);\n const dragOffset = useRef({ x: 0, y: 0 });\n const containerRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Prefer the server-stored conversation.name (sanitized) once loaded;\n // fall back to the local builder against patientData while we're still\n // waiting for the preview.\n const titleText =\n cleanChannelName(loadedConversation?.name) || buildChannelName(patientData);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n // Only allow dragging from the drag handle area\n if (!(e.target as HTMLElement).closest('[data-drag-handle]')) return;\n\n setIsDragging(true);\n dragOffset.current = {\n x: e.clientX - position.x,\n y: e.clientY - position.y,\n };\n e.preventDefault();\n },\n [position]\n );\n\n // ESC closes; Tab is constrained inside the popup so keyboard users can't\n // accidentally leave the dialog into the page behind. On open we move focus\n // into the popup; on close we put it back where it came from.\n useEffect(() => {\n if (!isOpen) return;\n\n previouslyFocused.current = document.activeElement as HTMLElement | null;\n\n // Defer one frame so the dialog contents have mounted before we look for\n // focusables (CollabPanel renders async branches).\n const focusFirst = () => {\n const root = containerRef.current;\n if (!root) return;\n const first = root.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n (first ?? root).focus();\n };\n const raf = requestAnimationFrame(focusFirst);\n\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose();\n return;\n }\n if (e.key !== 'Tab') return;\n\n const root = containerRef.current;\n if (!root) return;\n const focusables = Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));\n if (focusables.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n window.addEventListener('keydown', handleKey);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener('keydown', handleKey);\n previouslyFocused.current?.focus?.();\n };\n }, [isOpen, onClose]);\n\n useEffect(() => {\n if (!isDragging) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n setPosition({\n x: Math.max(0, Math.min(e.clientX - dragOffset.current.x, window.innerWidth - width)),\n y: Math.max(0, Math.min(e.clientY - dragOffset.current.y, window.innerHeight - (isMinimized ? 52 : height))),\n });\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isDragging, width, height, isMinimized]);\n\n if (!isOpen) return null;\n\n return (\n <div\n ref={containerRef}\n className={[ROOT_CLASS, className].filter(Boolean).join(' ')}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n tabIndex={-1}\n style={{\n ...styles.container,\n left: position.x,\n top: position.y,\n width,\n height: isMinimized ? 52 : height,\n cursor: isDragging ? 'grabbing' : 'default',\n }}\n onMouseDown={handleMouseDown}\n >\n {/* Window header β€” clean white bar with the patient identifier\n front and centre. Whole bar is still the drag handle; the\n interactive buttons stop drag via their own click handlers. */}\n <div data-drag-handle style={styles.titleBar}>\n {onBack && (\n <button\n onClick={onBack}\n style={styles.titleSquare}\n aria-label=\"Back to messages\"\n title=\"Back\"\n type=\"button\"\n >\n <BackIcon size={18} color={COLOR.neutral700} />\n </button>\n )}\n\n <div style={styles.titleCenter}>\n <h2 id={titleId} style={styles.patientName}>\n {patientData.patientName || titleText}\n </h2>\n {(patientData.labName || patientData.displayOrderId) && (\n <div style={styles.subRow}>\n {patientData.labName && <span>{patientData.labName}</span>}\n {patientData.labName && patientData.displayOrderId && (\n <span style={styles.subDot} aria-hidden=\"true\">Β·</span>\n )}\n {patientData.displayOrderId && (\n <span style={styles.mono}>\n #{patientData.displayOrderId.slice(-4)}\n </span>\n )}\n </div>\n )}\n </div>\n\n <div style={styles.titleActions}>\n <button\n onClick={() => {\n if (onMinimize) onMinimize();\n else setIsMinimized(!isMinimized);\n }}\n style={styles.titleSquare}\n aria-label={\n onMinimize\n ? 'Minimize chat'\n : isMinimized\n ? 'Expand chat'\n : 'Minimize chat'\n }\n title={\n onMinimize\n ? 'Minimize'\n : isMinimized\n ? 'Expand'\n : 'Minimize'\n }\n type=\"button\"\n >\n {onMinimize || !isMinimized ? (\n <MinimizeIcon size={18} color={COLOR.neutral700} />\n ) : (\n <ExpandIcon size={18} color={COLOR.neutral700} />\n )}\n </button>\n <button\n onClick={onClose}\n style={styles.titleSquare}\n aria-label=\"Close chat\"\n title=\"Close\"\n type=\"button\"\n >\n <CloseIcon size={18} color={COLOR.neutral700} />\n </button>\n </div>\n </div>\n\n {/* Panel content */}\n {!isMinimized && (\n <div style={styles.panelWrapper}>\n <CollabPanel\n orderId={orderId}\n patientData={patientData}\n participantIds={participantIds}\n hidePatientName\n onConversationChange={setLoadedConversation}\n />\n </div>\n )}\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n position: 'fixed',\n zIndex: Z_INDEX.dialog,\n borderRadius: '20px',\n boxShadow: '0 20px 48px rgba(20, 21, 28, 0.16), 0 6px 16px rgba(20, 21, 28, 0.08)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n transition: 'height 0.2s ease',\n fontFamily: FONT_STACK,\n },\n titleBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `10px ${SPACE.S3}`,\n backgroundColor: COLOR.white,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n cursor: 'grab',\n userSelect: 'none',\n flexShrink: 0,\n },\n titleCenter: {\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n },\n patientName: {\n margin: 0,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '-0.01em',\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n subDot: {\n color: COLOR.neutral400,\n },\n mono: {\n fontFamily:\n \"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontVariantNumeric: 'tabular-nums',\n },\n titleActions: {\n display: 'flex',\n gap: SPACE.S1,\n flexShrink: 0,\n },\n titleSquare: {\n width: '36px',\n height: '36px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: COLOR.neutral100,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.md,\n cursor: 'pointer',\n color: COLOR.neutral700,\n flexShrink: 0,\n },\n panelWrapper: {\n flex: 1,\n overflow: 'hidden',\n },\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type {\n ConversationPreview,\n Message,\n Participant,\n PatientData,\n SendMessagePayload,\n} from '../core/types';\nimport { buildChannelName } from '../core/channelName';\n\ninterface UseInlineCollabOptions {\n orderId: string;\n patientData: PatientData;\n /** Participant IDs passed to the backend only when creating a new conversation */\n participantIds?: string[];\n /** Max messages to keep in inline state (default 5) */\n messageLimit?: number;\n}\n\ninterface UseInlineCollabReturn {\n hasConversation: boolean;\n messages: Message[];\n participants: Participant[];\n unreadCount: number;\n isLoading: boolean;\n isSubscribed: boolean;\n error: string | null;\n sendMessage: (body: string) => Promise<void>;\n /** Send a voice message β€” uploads the blob via config.onUploadFile first */\n sendAudioMessage: (audioBlob: Blob, duration: number) => Promise<void>;\n /** Attach to the DOM element that represents the row β€” drives lazy socket subscription */\n containerRef: (element: HTMLElement | null) => void;\n}\n\n/**\n * Lightweight hook for inline chat in table rows.\n *\n * Behavior:\n * - On mount: fetches preview (batched) β€” no socket work\n * - If conversation exists AND row becomes visible: joins Phoenix channel (real-time)\n * - If row scrolls out of view: leaves channel (frees resources)\n * - First sendMessage creates conversation atomically + starts real-time flow\n * - Subsequent sends go through the socket\n */\nexport function useInlineCollab({\n orderId,\n patientData,\n participantIds = [],\n messageLimit = 5,\n}: UseInlineCollabOptions): UseInlineCollabReturn {\n const {\n socket,\n config,\n requestPreview,\n invalidatePreview,\n createConversationWithMessage,\n } = useCollab();\n\n const [preview, setPreview] = useState<ConversationPreview | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const [participants, setParticipants] = useState<Participant[]>([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [isLoading, setIsLoading] = useState(true);\n const [isSubscribed, setIsSubscribed] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const elementRef = useRef<HTMLElement | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const subscribedConversationIdRef = useRef<string | null>(null);\n // Holds the per-subscriber release function returned by socket.joinConversation.\n // See the equivalent ref in useConversation.ts for rationale.\n const channelSubscriptionRef = useRef<{ release: () => void } | null>(null);\n\n const trimToLimit = useCallback(\n (msgs: Message[]): Message[] =>\n msgs.length > messageLimit ? msgs.slice(msgs.length - messageLimit) : msgs,\n [messageLimit]\n );\n\n const buildName = useCallback(\n (): string => buildChannelName(patientData),\n [patientData]\n );\n\n // ── Fetch preview on mount (batched) ──\n useEffect(() => {\n let cancelled = false;\n\n const load = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const result = await requestPreview(orderId);\n if (cancelled) return;\n setPreview(result);\n if (result) {\n setMessages(trimToLimit(result.lastMessages));\n setParticipants(result.participants);\n setUnreadCount(result.unreadCount);\n }\n } catch (err) {\n if (cancelled) return;\n setError(err instanceof Error ? err.message : 'Failed to load preview');\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n load();\n return () => {\n cancelled = true;\n };\n }, [orderId, requestPreview, trimToLimit]);\n\n // ── Subscribe/unsubscribe socket based on visibility ──\n const subscribe = useCallback(\n (conversationId: string) => {\n if (subscribedConversationIdRef.current === conversationId) return;\n\n // Release any prior subscription before binding a new one.\n channelSubscriptionRef.current?.release();\n channelSubscriptionRef.current = null;\n\n const subscription = socket.joinConversation(conversationId, {\n onMessage: (msg) => {\n setMessages((prev) => trimToLimit([...prev, msg]));\n if (msg.senderId !== config.userId) {\n setUnreadCount((prev) => prev + 1);\n }\n },\n onUserJoined: (participant) => {\n setParticipants((prev) =>\n prev.some((p) => p.userId === participant.userId) ? prev : [...prev, participant]\n );\n },\n onUserLeft: (participant) => {\n setParticipants((prev) => prev.filter((p) => p.userId !== participant.userId));\n },\n });\n\n channelSubscriptionRef.current = subscription;\n subscribedConversationIdRef.current = conversationId;\n setIsSubscribed(true);\n },\n [socket, trimToLimit, config.userId]\n );\n\n const unsubscribe = useCallback(() => {\n // Release this hook's listeners only β€” the channel survives if a\n // sibling subscriber (e.g. an expanded CollabPanel) is still holding it.\n channelSubscriptionRef.current?.release();\n channelSubscriptionRef.current = null;\n subscribedConversationIdRef.current = null;\n setIsSubscribed(false);\n }, []);\n\n // ── IntersectionObserver lifecycle ──\n const containerRef = useCallback(\n (element: HTMLElement | null) => {\n // Teardown old observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n elementRef.current = element;\n if (!element) return;\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n if (!entry) return;\n\n const convId = preview?.conversationId;\n if (!convId) return;\n\n if (entry.isIntersecting) {\n subscribe(convId);\n } else {\n unsubscribe();\n }\n },\n { threshold: 0.1 }\n );\n\n observerRef.current.observe(element);\n },\n [preview, subscribe, unsubscribe]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (observerRef.current) observerRef.current.disconnect();\n unsubscribe();\n };\n }, [unsubscribe]);\n\n // Re-attach observer when preview becomes available after element is mounted\n useEffect(() => {\n if (preview?.conversationId && elementRef.current && !observerRef.current) {\n containerRef(elementRef.current);\n }\n }, [preview, containerRef]);\n\n // ── Internal: send a message payload, lazy-creating the conversation on the first send ──\n const dispatchSend = useCallback(\n async (payload: SendMessagePayload) => {\n if (!preview) {\n // First message β€” create conversation + send atomically\n try {\n const result = await createConversationWithMessage(orderId, payload, {\n name: buildName(),\n participantIds,\n });\n\n const newPreview: ConversationPreview = {\n conversationId: result.conversation.id,\n orderId,\n messageCount: 1,\n unreadCount: 0,\n lastMessages: [result.message],\n participants: result.conversation.participants,\n name: result.conversation.name,\n };\n\n setPreview(newPreview);\n setMessages([result.message]);\n setParticipants(result.conversation.participants);\n invalidatePreview(orderId);\n\n if (elementRef.current) {\n subscribe(result.conversation.id);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send first message',\n details: err,\n });\n }\n return;\n }\n\n try {\n await socket.sendMessage(preview.conversationId, payload);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send message',\n details: err,\n });\n }\n },\n [\n preview,\n orderId,\n buildName,\n participantIds,\n createConversationWithMessage,\n invalidatePreview,\n subscribe,\n socket,\n config,\n ]\n );\n\n const sendMessage = useCallback(\n async (body: string) => {\n const trimmed = body.trim();\n if (!trimmed) return;\n await dispatchSend({ body: trimmed, type: 'text' });\n },\n [dispatchSend]\n );\n\n const sendAudioMessage = useCallback(\n async (audioBlob: Blob, duration: number) => {\n if (!config.onUploadFile) {\n setError('File upload is not configured');\n return;\n }\n try {\n const url = await config.onUploadFile(audioBlob, 'voice-message.webm');\n await dispatchSend({\n body: 'Voice message',\n type: 'audio',\n media_url: url,\n media_duration: duration,\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to send voice message');\n config.onError?.({\n code: 'SEND_ERROR',\n message: 'Failed to send voice message',\n details: err,\n });\n }\n },\n [config, dispatchSend]\n );\n\n return {\n hasConversation: !!preview,\n messages,\n participants,\n unreadCount,\n isLoading,\n isSubscribed,\n error,\n sendMessage,\n sendAudioMessage,\n containerRef,\n };\n}\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { useInlineCollab } from '../hooks/useInlineCollab';\n// MIC DISABLED β€” voice messaging temporarily removed. Imports kept for easy re-enable.\n// import { useAudioRecorder } from '../hooks/useAudioRecorder';\n// import { MicIcon } from './icons/MicIcon';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { Message, PatientData, UserRole } from '../core/types';\n\nensureGlobalStyles();\n\ntype ColabInlineMode = 'light' | 'dark';\n\ninterface CollabInlinePalette {\n bg: string;\n border: string;\n previewBorder: string;\n senderName: string;\n messageText: string;\n systemText: string;\n inputBg: string;\n inputBorder: string;\n inputText: string;\n audioBg: string;\n audioFg: string;\n expandBorder: string;\n expandColor: string;\n}\n\nfunction palette(mode: ColabInlineMode): CollabInlinePalette {\n if (mode === 'dark') {\n return {\n bg: 'transparent',\n border: 'transparent',\n previewBorder: '#1f1f23',\n senderName: '#f3f4f6',\n messageText: '#cbd5e1',\n systemText: '#6b7280',\n inputBg: '#18181c',\n inputBorder: '#2a2a2e',\n inputText: '#e5e7eb',\n audioBg: 'rgba(37, 99, 235, 0.18)',\n audioFg: '#93c5fd',\n expandBorder: '#2a2a2e',\n expandColor: '#9ca3af',\n };\n }\n return {\n bg: COLOR.white,\n border: COLOR.neutral200,\n previewBorder: COLOR.neutral100,\n senderName: COLOR.neutral700,\n messageText: COLOR.neutral600,\n systemText: COLOR.neutral400,\n inputBg: 'transparent',\n inputBorder: COLOR.neutral200,\n inputText: COLOR.neutral900,\n audioBg: COLOR.primaryBg,\n audioFg: COLOR.primary,\n expandBorder: COLOR.neutral200,\n expandColor: COLOR.neutral500,\n };\n}\n\ninterface CollabInlineProps {\n orderId: string;\n patientData: PatientData;\n /** User IDs to invite when the first message creates the conversation */\n participantIds?: string[];\n /** Called when user clicks the expand button β€” host opens the floating popup */\n onExpand?: () => void;\n /** Max inline messages to show (default 1 β€” just the latest) */\n messageLimit?: number;\n /** Placeholder text for the input */\n placeholder?: string;\n /**\n * Color mode for the inline surface. Defaults to 'light'. 'dark' is meant\n * for embedding inside the viewer's left panel (black background) β€” only\n * neutral/structural colors switch; brand/role/semantic colors stay the\n * same in both modes.\n */\n mode?: ColabInlineMode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Inline chat for table rows or side panels.\n *\n * Two states:\n * - No conversation yet: just an input bar (no socket, no preview)\n * - Conversation exists: latest message (or last N if messageLimit > 1)\n * + input + expand button\n *\n * Supports text and voice messages. File attachments and full chat features\n * stay in the floating popup / inbox.\n */\nexport function CollabInline({\n orderId,\n patientData,\n participantIds,\n onExpand,\n messageLimit = 1,\n placeholder = 'Type a message about this case...',\n mode = 'light',\n className,\n style,\n}: CollabInlineProps) {\n const pal = palette(mode);\n const {\n hasConversation,\n messages,\n unreadCount,\n isLoading,\n isSubscribed,\n error,\n sendMessage,\n sendAudioMessage,\n containerRef,\n } = useInlineCollab({ orderId, patientData, participantIds, messageLimit });\n\n const containerStyle: React.CSSProperties = {\n ...styles.container,\n backgroundColor: pal.bg,\n borderColor: pal.border,\n ...style,\n };\n\n if (isLoading && !hasConversation) {\n return (\n <div className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={containerStyle}>\n <div style={styles.loadingState}>Loading...</div>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className={[ROOT_CLASS, className].filter(Boolean).join(' ')} style={containerStyle}>\n {hasConversation && messages.length > 0 && (\n <div style={{ ...styles.preview, borderBottomColor: pal.previewBorder }}>\n {messages.slice(-messageLimit).map((message) => (\n <InlineMessageRow key={message.id} message={message} pal={pal} />\n ))}\n </div>\n )}\n\n {error && <div style={styles.error}>{error}</div>}\n\n <InlineInputBar\n onSend={sendMessage}\n onSendAudio={sendAudioMessage}\n placeholder={placeholder}\n unreadCount={hasConversation ? unreadCount : 0}\n isLive={isSubscribed}\n showExpand={hasConversation && !!onExpand}\n onExpand={onExpand}\n pal={pal}\n />\n </div>\n );\n}\n\n// ─────────────────────────────────────────\n// Sub-components\n// ─────────────────────────────────────────\n\nfunction InlineMessageRow({ message, pal }: { message: Message; pal: CollabInlinePalette }) {\n if (message.type === 'system') {\n return (\n <div style={styles.systemRow}>\n <span style={{ ...styles.systemText, color: pal.systemText }}>{message.body}</span>\n </div>\n );\n }\n\n // Audio gets a compact play/pause + duration player inline\n if (message.type === 'audio' && message.mediaUrl) {\n return (\n <div style={styles.messageRow}>\n <RoleDot role={message.senderRole} />\n <span style={{ ...styles.senderName, color: pal.senderName }}>{message.senderName}:</span>\n <InlineAudioPlayer url={message.mediaUrl} duration={message.mediaDuration} pal={pal} />\n </div>\n );\n }\n\n const preview = renderMessagePreview(message);\n\n return (\n <div style={styles.messageRow}>\n <RoleDot role={message.senderRole} />\n <span style={{ ...styles.senderName, color: pal.senderName }}>{message.senderName}:</span>\n <span style={{ ...styles.messageText, color: pal.messageText }}>{preview}</span>\n </div>\n );\n}\n\nfunction RoleDot({ role }: { role: UserRole }) {\n // Cool-only palette β€” matches MessageBubble.roleColor() so the inline\n // preview reads the same as the full chat. See that helper for the\n // rationale (no greens / reds / purples on the chat surfaces).\n const colors: Record<UserRole, string> = {\n radiologist: '#4f46e5', // indigo\n lab: '#2563eb', // brand blue\n physician: '#0284c7', // sky\n admin: '#64748b', // slate\n };\n\n return <span style={{ ...styles.roleDot, backgroundColor: colors[role] }} />;\n}\n\n/**\n * Compact audio player designed to fit in a single inline row.\n * Shows just a play/pause toggle + duration. No scrubber.\n */\nfunction InlineAudioPlayer({\n url,\n duration,\n pal,\n}: {\n url: string;\n duration?: number;\n pal: CollabInlinePalette;\n}) {\n const audioRef = useRef<HTMLAudioElement>(null);\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n\n const toggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n const audio = audioRef.current;\n if (!audio) return;\n if (isPlaying) {\n audio.pause();\n } else {\n audio.play().catch(() => {\n // Silent fail β€” autoplay blocked, etc.\n });\n }\n },\n [isPlaying]\n );\n\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => {\n setIsPlaying(false);\n setCurrentTime(0);\n };\n const onTimeUpdate = () => setCurrentTime(audio.currentTime);\n\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('timeupdate', onTimeUpdate);\n\n return () => {\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('timeupdate', onTimeUpdate);\n };\n }, []);\n\n const total = duration ?? 0;\n const remaining = Math.max(0, total - Math.floor(currentTime));\n const displayTime = isPlaying ? remaining : total;\n\n return (\n <span style={{ ...styles.audioPlayer, backgroundColor: pal.audioBg, borderColor: pal.audioBg }}>\n <button\n onClick={toggle}\n style={styles.audioButton}\n title={isPlaying ? 'Pause' : 'Play'}\n type=\"button\"\n >\n {isPlaying ? '⏸' : 'β–Ά'}\n </button>\n <span style={styles.audioWaveform}>\n {/* Purely decorative bars */}\n <span style={{ ...styles.waveBar, height: '40%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '80%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '60%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '90%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '50%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '70%', backgroundColor: pal.audioFg }} />\n <span style={{ ...styles.waveBar, height: '40%', backgroundColor: pal.audioFg }} />\n </span>\n <span style={{ ...styles.audioDuration, color: pal.audioFg }}>{formatDuration(displayTime)}</span>\n <audio ref={audioRef} src={url} preload=\"metadata\" />\n </span>\n );\n}\n\nfunction renderMessagePreview(message: Message): string {\n switch (message.type) {\n case 'image':\n return `πŸ“· ${message.fileName || 'Image'}`;\n case 'file':\n return `πŸ“Ž ${message.fileName || 'File'}`;\n case 'deep_link':\n return `πŸ”— ${message.body}`;\n default:\n return message.body;\n }\n}\n\nfunction formatDuration(seconds: number): string {\n const safe = Math.max(0, Math.floor(seconds));\n const m = Math.floor(safe / 60);\n const s = safe % 60;\n return `${m}:${s.toString().padStart(2, '0')}`;\n}\n\ninterface InlineInputBarProps {\n onSend: (body: string) => Promise<void>;\n /** @deprecated MIC DISABLED β€” kept in prop signature for backward compat. */\n onSendAudio?: (blob: Blob, duration: number) => Promise<void>;\n placeholder: string;\n unreadCount: number;\n isLive: boolean;\n showExpand: boolean;\n onExpand?: () => void;\n pal: CollabInlinePalette;\n}\n\nfunction InlineInputBar({\n onSend,\n // MIC DISABLED β€” onSendAudio accepted but unused.\n // onSendAudio,\n placeholder,\n unreadCount,\n isLive,\n showExpand,\n onExpand,\n pal,\n}: InlineInputBarProps) {\n const [text, setText] = useState('');\n const [isSending, setIsSending] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // MIC DISABLED β€” voice recorder hook + handlers not invoked. Restore by\n // uncommenting the destructure and handleStopRecording below (and the\n // imports at the top of the file).\n // const {\n // isRecording,\n // duration,\n // start: startRecording,\n // stop: stopRecording,\n // cancel: cancelRecording,\n // isSupported: micSupported,\n // error: micError,\n // } = useAudioRecorder();\n\n const handleSend = useCallback(async () => {\n const trimmed = text.trim();\n if (!trimmed || isSending) return;\n\n setIsSending(true);\n try {\n await onSend(trimmed);\n setText('');\n inputRef.current?.focus();\n } finally {\n setIsSending(false);\n }\n }, [text, isSending, onSend]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n },\n [handleSend]\n );\n\n // MIC DISABLED β€” audio stop handler unused. Restore alongside useAudioRecorder.\n // const handleStopRecording = useCallback(async () => {\n // const result = await stopRecording();\n // if (result) {\n // setIsSending(true);\n // try {\n // await onSendAudio(result.blob, result.duration);\n // } finally {\n // setIsSending(false);\n // }\n // }\n // }, [stopRecording, onSendAudio]);\n\n /* MIC DISABLED β€” recording mode branch removed. Original block kept here\n for easy re-enable when mic is restored:\n\n if (isRecording) {\n return (\n <div style={styles.recordingBar}>\n <span style={styles.recordingDot} />\n <span style={styles.recordingLabel}>Recording {formatDuration(duration)}</span>\n <button onClick={cancelRecording} style={styles.recordingCancel} title=\"Cancel recording\" type=\"button\">Cancel</button>\n <button onClick={handleStopRecording} style={styles.recordingSend} title=\"Send voice message\" type=\"button\">Send</button>\n </div>\n );\n }\n */\n\n return (\n <div style={styles.inputBar}>\n <input\n ref={inputRef}\n type=\"text\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={isSending}\n style={{\n ...styles.input,\n backgroundColor: pal.inputBg,\n borderColor: pal.inputBorder,\n color: pal.inputText,\n }}\n />\n\n {unreadCount > 0 && (\n <span style={styles.unreadBadge} title={`${unreadCount} unread`}>\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n\n {isLive && <span style={styles.liveDot} title=\"Live updates active\" />}\n\n {/* MIC DISABLED β€” mic button hidden. Original block:\n {micSupported && !text.trim() && (\n <button onClick={startRecording} disabled={isSending} style={styles.micButton} title=\"Record voice message\" type=\"button\">\n <MicIcon size={16} color=\"#374151\" />\n </button>\n )}\n */}\n\n {/* Send button β€” shown when there's text to send */}\n {text.trim() && (\n <button\n onClick={handleSend}\n disabled={isSending}\n style={styles.sendButton}\n title=\"Send message\"\n type=\"button\"\n >\n ➀\n </button>\n )}\n\n {showExpand && onExpand && (\n <button\n onClick={onExpand}\n style={{\n ...styles.expandButton,\n borderColor: pal.expandBorder,\n color: pal.expandColor,\n }}\n title=\"Expand to full chat\"\n type=\"button\"\n >\n β›Ά\n </button>\n )}\n </div>\n );\n}\n\n// ─────────────────────────────────────────\n// Styles\n// ─────────────────────────────────────────\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n padding: `${SPACE.S1} ${SPACE.S2}`,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.md,\n fontFamily: FONT_STACK,\n },\n loadingState: {\n padding: SPACE.S2,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n textAlign: 'center',\n },\n error: {\n padding: `${SPACE.S1} ${SPACE.S2}`,\n marginBottom: SPACE.S1,\n fontSize: FONT_SIZE.xs,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n borderRadius: RADIUS.sm,\n },\n preview: {\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n marginBottom: SPACE.S1,\n paddingBottom: SPACE.S1,\n borderBottom: `1px solid ${COLOR.neutral100}`,\n },\n messageRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n fontSize: FONT_SIZE.xs,\n lineHeight: LINE_HEIGHT.normal,\n overflow: 'hidden',\n },\n roleDot: {\n flexShrink: 0,\n width: '6px',\n height: '6px',\n borderRadius: RADIUS.full,\n },\n senderName: {\n flexShrink: 0,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n messageText: {\n color: COLOR.neutral600,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n flex: 1,\n },\n systemRow: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral400,\n fontStyle: 'italic',\n textAlign: 'center',\n padding: '2px 0',\n },\n systemText: {\n opacity: 0.8,\n },\n // ── Audio player (inline) ──\n audioPlayer: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `2px ${SPACE.S2}`,\n borderRadius: RADIUS.lg,\n backgroundColor: COLOR.primaryBg,\n border: `1px solid ${COLOR.primaryBg}`,\n flex: 1,\n minWidth: 0,\n },\n audioButton: {\n width: '20px',\n height: '20px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.xs,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n flexShrink: 0,\n },\n audioWaveform: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '2px',\n height: SPACE.S4,\n flex: 1,\n minWidth: 0,\n },\n waveBar: {\n display: 'inline-block',\n width: '2px',\n borderRadius: '1px',\n backgroundColor: COLOR.primary,\n },\n audioDuration: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.primary,\n fontVariantNumeric: 'tabular-nums',\n fontWeight: FONT_WEIGHT.medium,\n flexShrink: 0,\n },\n // ── Input bar ──\n inputBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n },\n input: {\n flex: 1,\n padding: `${SPACE.S2} ${SPACE.S3}`,\n fontSize: FONT_SIZE.sm,\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.pill,\n outline: 'none',\n fontFamily: 'inherit',\n minWidth: 0,\n },\n unreadBadge: {\n flexShrink: 0,\n minWidth: '18px',\n height: '18px',\n padding: `0 ${SPACE.S1}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n borderRadius: RADIUS.pill,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n liveDot: {\n flexShrink: 0,\n width: '6px',\n height: '6px',\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.success,\n },\n micButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n backgroundColor: COLOR.neutral100,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n sendButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.sm,\n color: COLOR.white,\n backgroundColor: COLOR.primary,\n border: 'none',\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n expandButton: {\n flexShrink: 0,\n width: '28px',\n height: '28px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: 'transparent',\n border: `1px solid ${COLOR.neutral200}`,\n borderRadius: RADIUS.full,\n cursor: 'pointer',\n },\n // ── Recording mode ──\n recordingBar: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S1} ${SPACE.S3}`,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.pill,\n },\n recordingDot: {\n width: SPACE.S2,\n height: SPACE.S2,\n borderRadius: RADIUS.full,\n backgroundColor: COLOR.danger,\n flexShrink: 0,\n animation: 'pulse 1.5s infinite',\n },\n recordingLabel: {\n flex: 1,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.danger,\n fontVariantNumeric: 'tabular-nums',\n },\n recordingCancel: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n backgroundColor: COLOR.white,\n border: `1px solid ${COLOR.neutral300}`,\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n flexShrink: 0,\n },\n recordingSend: {\n padding: `${SPACE.S1} ${SPACE.S3}`,\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n border: 'none',\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n flexShrink: 0,\n },\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { ConversationListItem } from '../core/types';\n\ninterface UseConversationListOptions {\n /**\n * When false, skips the initial auto-fetch. The caller can still invoke\n * `refresh()` manually (e.g. on user interaction). Defaults to true.\n */\n enabled?: boolean;\n}\n\ninterface UseConversationListReturn {\n conversations: ConversationListItem[];\n isLoading: boolean;\n error: string | null;\n refresh: () => Promise<void>;\n /** Filter conversations by query string (matches channel name + patient name) */\n filter: (query: string) => ConversationListItem[];\n /** Total unread across all conversations */\n totalUnread: number;\n}\n\n/**\n * Fetches the current user's full conversation list for the inbox.\n * Conversations are returned sorted by last activity (backend-sorted).\n *\n * Pass `{ enabled: false }` for lazy mode β€” useful when the list is behind\n * a click (e.g. a collapsed FAB panel) and you don't want to hit the API\n * until the user opens it.\n */\nexport function useConversationList(\n options?: UseConversationListOptions\n): UseConversationListReturn {\n const enabled = options?.enabled ?? true;\n const { fetchConversationList, config, totalUnread: serverTotalUnread } =\n useCollab();\n const [conversations, setConversations] = useState<ConversationListItem[]>([]);\n const [isLoading, setIsLoading] = useState(enabled);\n const [error, setError] = useState<string | null>(null);\n\n // Silent refresh (no spinner flash) β€” used for socket-driven resyncs so a\n // background update doesn't blink the list.\n const silentRefresh = useCallback(async () => {\n try {\n const list = await fetchConversationList();\n setConversations(list);\n } catch (err) {\n config.onError?.({\n code: 'LIST_ERROR',\n message: err instanceof Error ? err.message : 'Failed to load conversations',\n details: err,\n });\n }\n }, [fetchConversationList, config]);\n\n const refresh = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const list = await fetchConversationList();\n setConversations(list);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to load conversations';\n setError(msg);\n config.onError?.({\n code: 'LIST_ERROR',\n message: msg,\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [fetchConversationList, config]);\n\n useEffect(() => {\n if (!enabled) return;\n refresh();\n }, [enabled, refresh]);\n\n // Live resync: the server pushes an `unread_update` event on the user\n // notifications channel any time a message arrives, gets read, etc.\n // CollabProvider surfaces that as `serverTotalUnread`. When it changes\n // and the list is currently showing, pull fresh data silently so the\n // last-message / activity order / unread badges all stay in sync without\n // the user having to close and reopen the panel.\n //\n // Skip the first run β€” the main effect above already handled mount,\n // firing a silent refetch here on top would double-fetch.\n const hasHandledInitialUnreadRef = useRef(false);\n useEffect(() => {\n if (!enabled) return;\n if (!hasHandledInitialUnreadRef.current) {\n hasHandledInitialUnreadRef.current = true;\n return;\n }\n silentRefresh();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [serverTotalUnread, enabled]);\n\n const filter = useCallback(\n (query: string): ConversationListItem[] => {\n const q = query.trim().toLowerCase();\n if (!q) return conversations;\n return conversations.filter((c) => {\n const patient = c.patientSnapshot?.patientName?.toLowerCase() || '';\n const name = c.name.toLowerCase();\n return name.includes(q) || patient.includes(q);\n });\n },\n [conversations]\n );\n\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n\n return {\n conversations,\n isLoading,\n error,\n refresh,\n filter,\n totalUnread,\n };\n}\n","import React from 'react';\nimport type { ConversationListItem as ListItem, Message } from '../core/types';\nimport { formatInboxTimestamp } from '../core/dateLabels';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\n\ninterface ConversationListItemProps {\n item: ListItem;\n isSelected: boolean;\n onClick: () => void;\n className?: string;\n}\n\n/**\n * Single row in the inbox sidebar.\n *\n * Three-row layout (top-to-bottom):\n * 1. Patient/channel name + relative time\n * 2. Study type + monospace `MRN <patientId>` (surfaced from the\n * snapshot; either field is optional and the row collapses if both\n * are missing)\n * 3. Last message preview (sender prefix in stronger weight) + unread\n * count badge on the right\n *\n * Active row gets a 4px brand-color left-border accent + tinted background.\n * The avatar is a 52px **square** tile (16px rounded corners) with brand-\n * coloured fill and white initials β€” easier to scan than a circle at this\n * size and consistent across the inbox without depending on any case\n * status field we don't model.\n */\nexport function ConversationListItem({\n item,\n isSelected,\n onClick,\n className,\n}: ConversationListItemProps) {\n const hasUnread = item.unreadCount > 0;\n const displayName = item.name || item.patientSnapshot?.patientName || 'Unknown';\n const studyType = item.patientSnapshot?.studyType;\n const patientId = item.patientSnapshot?.patientId;\n const showStudyRow = !!(studyType || patientId);\n const initials = computeInitials(item.patientSnapshot?.patientName || displayName);\n\n return (\n <button\n className={className}\n onClick={onClick}\n style={{\n ...styles.container,\n ...(isSelected ? styles.selected : {}),\n }}\n type=\"button\"\n >\n {/* Avatar β€” square tile with rounded corners, brand-coloured */}\n <div style={styles.avatarWrapper}>\n {item.picture ? (\n <img src={item.picture} alt=\"\" style={styles.avatarImg} />\n ) : (\n <div style={styles.avatarTile} aria-hidden=\"true\">\n {initials}\n </div>\n )}\n </div>\n\n {/* Main content */}\n <div style={styles.content}>\n <div style={styles.topRow}>\n <span\n style={{\n ...styles.name,\n ...(hasUnread ? styles.nameUnread : {}),\n }}\n >\n {displayName}\n </span>\n <span\n style={{\n ...styles.time,\n ...(hasUnread ? styles.timeUnread : {}),\n }}\n >\n {formatInboxTimestamp(item.lastActivityAt)}\n </span>\n </div>\n\n {showStudyRow && (\n <div style={styles.studyRow}>\n {studyType && <span style={styles.studyType}>{studyType}</span>}\n {studyType && patientId && <span style={styles.studyDivider}>Β·</span>}\n {patientId && <span style={styles.studyId}>MRN {patientId}</span>}\n </div>\n )}\n\n <div style={styles.bottomRow}>\n <PreviewLine message={item.lastMessage} hasUnread={hasUnread} />\n {hasUnread && (\n <span style={styles.badge} aria-label={`${item.unreadCount} unread`}>\n {item.unreadCount > 99 ? '99+' : item.unreadCount}\n </span>\n )}\n </div>\n </div>\n </button>\n );\n}\n\nfunction PreviewLine({ message, hasUnread }: { message?: Message; hasUnread: boolean }) {\n if (!message) {\n return <span style={styles.preview}>No messages yet</span>;\n }\n if (message.type === 'system') {\n return <span style={styles.preview}>{message.body}</span>;\n }\n const text = previewText(message);\n const sender = message.senderName ? `${message.senderName.split(' ')[0]}:` : '';\n return (\n <span\n style={{\n ...styles.preview,\n ...(hasUnread ? styles.previewUnread : {}),\n }}\n >\n {sender && <span style={styles.previewSender}>{sender} </span>}\n {text}\n </span>\n );\n}\n\nfunction previewText(message: Message): string {\n switch (message.type) {\n case 'audio':\n return 'Voice message';\n case 'image':\n return message.fileName || 'Image';\n case 'file':\n return message.fileName || 'File';\n case 'deep_link':\n return message.body || 'Shared link';\n default: {\n const body = message.body || '';\n return body.length > 60 ? `${body.slice(0, 60)}…` : body;\n }\n }\n}\n\nfunction computeInitials(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((part) => part[0]?.toUpperCase() ?? '')\n .join('') || '?';\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '14px',\n width: '100%',\n padding: `14px ${SPACE.S5}`,\n minHeight: '84px',\n backgroundColor: 'transparent',\n border: 'none',\n borderLeft: '4px solid transparent',\n cursor: 'pointer',\n textAlign: 'left',\n color: 'inherit',\n fontFamily: 'inherit',\n transition: 'background-color 120ms ease',\n },\n selected: {\n backgroundColor: COLOR.primaryBg,\n borderLeftColor: COLOR.primary,\n },\n avatarWrapper: {\n width: '52px',\n height: '52px',\n flexShrink: 0,\n },\n avatarImg: {\n width: '52px',\n height: '52px',\n borderRadius: RADIUS.xl,\n objectFit: 'cover' as const,\n boxShadow: 'inset 0 -2px 0 rgba(0, 0, 0, 0.08)',\n },\n avatarTile: {\n width: '52px',\n height: '52px',\n borderRadius: RADIUS.xl,\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.bold,\n letterSpacing: '0.02em',\n boxShadow: 'inset 0 -2px 0 rgba(0, 0, 0, 0.08)',\n },\n content: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n gap: '3px',\n minWidth: 0,\n },\n topRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'baseline',\n gap: SPACE.S2,\n },\n name: {\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.medium,\n color: COLOR.neutral900,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n nameUnread: {\n fontWeight: FONT_WEIGHT.bold,\n },\n time: {\n fontSize: FONT_SIZE.xs,\n color: COLOR.neutral500,\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n timeUnread: {\n color: COLOR.primary,\n fontWeight: FONT_WEIGHT.semibold,\n },\n studyRow: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n minWidth: 0,\n },\n studyType: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n studyDivider: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral400,\n flexShrink: 0,\n },\n studyId: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n fontFamily:\n \"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n bottomRow: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: SPACE.S2,\n marginTop: '2px',\n },\n preview: {\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n previewSender: {\n color: COLOR.neutral700,\n fontWeight: FONT_WEIGHT.semibold,\n },\n previewUnread: {\n color: COLOR.neutral900,\n fontWeight: FONT_WEIGHT.medium,\n },\n badge: {\n minWidth: '22px',\n height: '22px',\n padding: '0 9px',\n fontSize: FONT_SIZE.xs,\n fontWeight: FONT_WEIGHT.bold,\n color: COLOR.white,\n backgroundColor: COLOR.danger,\n borderRadius: RADIUS.pill,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontVariantNumeric: 'tabular-nums',\n flexShrink: 0,\n },\n};\n","import React from 'react';\n\nexport function SearchIcon({ size = 20, color = 'currentColor' }: { size?: number; color?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M20 20l-4-4\" />\n </svg>\n );\n}\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { ConversationListItem } from './ConversationListItem';\nimport { SearchIcon } from './icons/SearchIcon';\nimport { ChatIllustration } from './icons/ChatIllustration';\nimport { Spinner } from './Spinner';\nimport { useCollab } from '../context/CollabProvider';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n LINE_HEIGHT,\n RADIUS,\n SPACE,\n} from '../core/theme';\nimport type { ConversationListItem as ListItem } from '../core/types';\n\ninterface ConversationListProps {\n conversations: ListItem[];\n selectedId: string | null;\n isLoading: boolean;\n error: string | null;\n onSelect: (item: ListItem) => void;\n className?: string;\n}\n\ntype Filter = 'all' | 'unread';\n\n/**\n * Scrollable inbox of conversations. Unread/All tabs (with count pills)\n * sit at the top, followed by a search field with a focus-within ring.\n * The inbox lands on Unread by default whenever there are any unread\n * conversations β€” the initial choice reads CollabProvider's socket-\n * pushed `totalUnread`, which is already populated by the time the\n * FAB is clicked (it drives the badge), so there's no \"All flash\"\n * during the conversation-list fetch. A fallback effect handles the\n * edge case where the conversation list loads with unread items but\n * `totalUnread` was still zero at mount time. Empty/loading/error\n * states are illustrated and descriptive rather than terse one-liners.\n */\nexport function ConversationList({\n conversations,\n selectedId,\n isLoading,\n error,\n onSelect,\n className,\n}: ConversationListProps) {\n const { totalUnread } = useCollab();\n const [query, setQuery] = useState('');\n // Function-form initializer so the decision is made once at mount,\n // before first paint β€” the user never sees the All tab as the\n // active tab when they have unread messages waiting.\n const [filter, setFilter] = useState<Filter>(() =>\n totalUnread > 0 ? 'unread' : 'all'\n );\n const [searchFocused, setSearchFocused] = useState(false);\n\n const unreadCount = useMemo(\n () => conversations.filter((c) => c.unreadCount > 0).length,\n [conversations]\n );\n\n // Fallback for the case where CollabProvider hadn't yet received the\n // server's first unread push at mount time (totalUnread was 0), but\n // the conversation list itself comes back with unread items. One-shot\n // via a ref so we never override a manual tab switch afterwards.\n const autoDefaultedRef = useRef(false);\n useEffect(() => {\n if (autoDefaultedRef.current) return;\n if (conversations.length === 0) return;\n autoDefaultedRef.current = true;\n if (unreadCount > 0) setFilter('unread');\n }, [conversations.length, unreadCount]);\n\n const filtered = useMemo(() => {\n let result = conversations;\n if (filter === 'unread') {\n result = result.filter((c) => c.unreadCount > 0);\n }\n const q = query.trim().toLowerCase();\n if (q) {\n result = result.filter((c) => {\n const name = c.name.toLowerCase();\n const patient = c.patientSnapshot?.patientName?.toLowerCase() || '';\n const studyType = c.patientSnapshot?.studyType?.toLowerCase() || '';\n const patientId = c.patientSnapshot?.patientId?.toLowerCase() || '';\n return (\n name.includes(q) ||\n patient.includes(q) ||\n studyType.includes(q) ||\n patientId.includes(q)\n );\n });\n }\n return result;\n }, [conversations, query, filter]);\n\n return (\n <div className={className} style={styles.container}>\n {/* Filter toggles β€” Unread first so it's the natural starting\n point when the inbox auto-defaults there on open. */}\n <div style={styles.tabs}>\n <TabButton\n label=\"Unread\"\n count={unreadCount}\n isActive={filter === 'unread'}\n onClick={() => setFilter('unread')}\n />\n <TabButton\n label=\"All\"\n count={conversations.length}\n isActive={filter === 'all'}\n onClick={() => setFilter('all')}\n />\n </div>\n\n {/* Search β€” focus-within glow */}\n <div\n style={{\n ...styles.search,\n ...(searchFocused ? styles.searchFocused : {}),\n }}\n >\n <span style={styles.searchIcon} aria-hidden=\"true\">\n <SearchIcon size={20} color={COLOR.neutral500} />\n </span>\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onFocus={() => setSearchFocused(true)}\n onBlur={() => setSearchFocused(false)}\n placeholder=\"Search by patient name or MRN\"\n aria-label=\"Search conversations\"\n style={styles.searchInput}\n />\n </div>\n\n {/* List */}\n <div style={styles.list}>\n {isLoading && (\n <div style={styles.loading}>\n <Spinner size={16} />\n <span>Loading conversations…</span>\n </div>\n )}\n\n {error && !isLoading && <div style={styles.errorState}>{error}</div>}\n\n {!isLoading && !error && filtered.length === 0 && (\n <EmptyState filter={filter} hasQuery={query.trim().length > 0} />\n )}\n\n {filtered.map((item) => (\n <ConversationListItem\n key={item.id}\n item={item}\n isSelected={selectedId === item.id}\n onClick={() => onSelect(item)}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction TabButton({\n label,\n count,\n isActive,\n onClick,\n}: {\n label: string;\n count: number;\n isActive: boolean;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n style={{\n ...styles.tab,\n ...(isActive ? styles.tabActive : {}),\n }}\n >\n <span>{label}</span>\n <span\n style={{\n ...styles.tabCount,\n ...(isActive ? styles.tabCountActive : {}),\n }}\n >\n {count}\n </span>\n </button>\n );\n}\n\nfunction EmptyState({ filter, hasQuery }: { filter: Filter; hasQuery: boolean }) {\n let title = 'No conversations yet';\n let subtitle = 'New chats will show up here as cases come in.';\n if (filter === 'unread') {\n title = 'No unread messages';\n subtitle = \"You're all caught up.\";\n } else if (hasQuery) {\n title = 'No conversations match';\n subtitle = 'Try a different search.';\n }\n return (\n <div style={styles.empty}>\n <ChatIllustration size={88} />\n <p style={styles.emptyTitle}>{title}</p>\n <p style={styles.emptySubtitle}>{subtitle}</p>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: COLOR.white,\n },\n // Tabs sit at the top of the panel now (header section removed).\n // A bit more top padding so they don't crowd the top edge.\n tabs: {\n display: 'flex',\n gap: SPACE.S2,\n padding: `${SPACE.S5} ${SPACE.S5} ${SPACE.S2}`,\n borderBottom: `1px solid ${COLOR.neutral200}`,\n flexShrink: 0,\n },\n tab: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: SPACE.S2,\n padding: `${SPACE.S2} ${SPACE.S4}`,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: RADIUS.lg,\n cursor: 'pointer',\n color: COLOR.neutral500,\n fontFamily: 'inherit',\n fontSize: FONT_SIZE.sm,\n fontWeight: FONT_WEIGHT.semibold,\n transition: 'background-color 120ms ease, color 120ms ease',\n },\n tabActive: {\n backgroundColor: COLOR.primaryBg,\n color: COLOR.primary,\n },\n tabCount: {\n fontSize: FONT_SIZE.xs,\n fontVariantNumeric: 'tabular-nums',\n padding: '1px 8px',\n borderRadius: RADIUS.pill,\n backgroundColor: COLOR.neutral200,\n color: COLOR.neutral500,\n fontWeight: FONT_WEIGHT.semibold,\n },\n tabCountActive: {\n backgroundColor: COLOR.primary,\n color: COLOR.white,\n },\n search: {\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.S2,\n margin: `14px ${SPACE.S5} ${SPACE.S3}`,\n padding: `${SPACE.S3} 14px`,\n backgroundColor: COLOR.neutral100,\n border: `1.5px solid ${COLOR.neutral200}`,\n borderRadius: '14px',\n transition: 'background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease',\n },\n searchFocused: {\n backgroundColor: COLOR.white,\n borderColor: COLOR.primary,\n boxShadow: `0 0 0 3px ${COLOR.primaryBg}`,\n },\n searchIcon: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n },\n searchInput: {\n flex: 1,\n minWidth: 0,\n border: 'none',\n background: 'transparent',\n outline: 'none',\n fontFamily: 'inherit',\n fontSize: FONT_SIZE.md,\n color: COLOR.neutral900,\n },\n list: {\n flex: 1,\n overflowY: 'auto',\n padding: '4px 0 12px',\n },\n loading: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE.S2,\n padding: `44px ${SPACE.S5}`,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n },\n errorState: {\n padding: SPACE.S4,\n margin: SPACE.S3,\n fontSize: FONT_SIZE.sm,\n color: COLOR.danger,\n backgroundColor: COLOR.dangerBg,\n border: `1px solid ${COLOR.dangerBorder}`,\n borderRadius: RADIUS.md,\n textAlign: 'center',\n },\n empty: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '44px 24px',\n textAlign: 'center',\n color: COLOR.neutral500,\n },\n emptyTitle: {\n margin: '12px 0 4px',\n fontSize: FONT_SIZE.md,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n emptySubtitle: {\n margin: 0,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n maxWidth: '280px',\n lineHeight: LINE_HEIGHT.normal,\n },\n};\n","import React, { useEffect, useState } from 'react';\nimport { useConversationList } from '../hooks/useConversationList';\nimport { ConversationList } from './ConversationList';\nimport { CollabPanel } from './CollabPanel';\nimport { FONT_STACK, ROOT_CLASS, ensureGlobalStyles } from '../core/styles';\nimport {\n COLOR,\n FONT_SIZE,\n FONT_WEIGHT,\n SPACE,\n} from '../core/theme';\nimport type { ConversationListItem, PatientData } from '../core/types';\n\nensureGlobalStyles();\n\n/** Width below which the inbox collapses to a single-pane list↔detail UX. */\nconst COMPACT_BREAKPOINT = 720;\n\ninterface CollabInboxProps {\n /** Optional: preselect a specific conversation (by conversation ID) */\n initialConversationId?: string;\n /** Optional callback when the user selects a conversation */\n onSelectConversation?: (item: ConversationListItem) => void;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Full-page inbox β€” WhatsApp-style sidebar of all user's conversations\n * with the selected conversation's CollabPanel on the right.\n *\n * Uses the same CollabPanel as the floating popup, so all features\n * (reply, pin, seen-by, DICOM, voice, attachments) are available.\n */\nexport function CollabInbox({\n initialConversationId,\n onSelectConversation,\n className,\n style,\n}: CollabInboxProps) {\n const { conversations, isLoading, error } = useConversationList();\n const [selectedId, setSelectedId] = useState<string | null>(initialConversationId ?? null);\n const [isCompact, setIsCompact] = useState<boolean>(() =>\n typeof window === 'undefined' ? false : window.innerWidth < COMPACT_BREAKPOINT\n );\n\n // Track viewport breakpoint at runtime β€” we keep both list and detail\n // mounted in wide layouts but render only one at a time on narrow screens\n // so phone/tablet users don't lose half the viewport to a 320px sidebar.\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia(`(max-width: ${COMPACT_BREAKPOINT - 1}px)`);\n const sync = () => setIsCompact(mq.matches);\n sync();\n mq.addEventListener('change', sync);\n return () => mq.removeEventListener('change', sync);\n }, []);\n\n const selected = conversations.find((c) => c.id === selectedId) || null;\n\n const handleSelect = (item: ConversationListItem) => {\n setSelectedId(item.id);\n onSelectConversation?.(item);\n };\n\n // In compact mode we toggle between list and detail. The \"back\" affordance\n // simply clears the selection so the list re-renders full-width.\n const showDetail = !isCompact || (isCompact && !!selected);\n const showList = !isCompact || (isCompact && !selected);\n\n return (\n <div\n className={[ROOT_CLASS, className].filter(Boolean).join(' ')}\n style={{ ...styles.container, ...style }}\n >\n {showList && (\n <div style={isCompact ? styles.sidebarCompact : styles.sidebar}>\n <ConversationList\n conversations={conversations}\n selectedId={selectedId}\n isLoading={isLoading}\n error={error}\n onSelect={handleSelect}\n />\n </div>\n )}\n\n {showDetail && (\n <div style={isCompact ? styles.mainCompact : styles.main}>\n {selected ? (\n <CollabPanel\n key={selected.id}\n orderId={selected.orderId}\n patientData={buildPatientData(selected)}\n showSeenBy={true}\n style={styles.panel}\n onBack={isCompact ? () => setSelectedId(null) : undefined}\n />\n ) : (\n <EmptyState hasAny={conversations.length > 0} />\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction buildPatientData(item: ConversationListItem): PatientData {\n // The server-stored channel name (item.name) is always in the canonical\n // \"<patient> - <lab> - <last4>\" form, so parse it and merge with the\n // patient snapshot. Older snapshots created before the backend started\n // resolving labName via UserLookup lack the lab field β€” without this\n // merge, the header would render \"<patient> - - <last4>\" while the\n // inbox row (which uses item.name) shows the correct lab name.\n const parsed = parseChannelName(item.name, item.orderId);\n\n if (item.patientSnapshot) {\n return {\n ...item.patientSnapshot,\n labName: item.patientSnapshot.labName ?? parsed.labName,\n displayOrderId: item.patientSnapshot.displayOrderId ?? parsed.displayOrderId,\n };\n }\n\n return parsed;\n}\n\nfunction parseChannelName(name: string, orderId: string): PatientData {\n // Format (from buildChannelName): \"<patient> - <lab> - <last4>\"\n const parts = name.split(' - ');\n if (parts.length >= 3) {\n const last4 = parts[parts.length - 1];\n const labName = parts[parts.length - 2];\n const patientName = parts.slice(0, parts.length - 2).join(' - ');\n return {\n patientName,\n labName: labName || undefined,\n orderId,\n displayOrderId: last4,\n };\n }\n\n return {\n patientName: name,\n orderId,\n };\n}\n\nfunction EmptyState({ hasAny }: { hasAny: boolean }) {\n return (\n <div style={styles.empty}>\n <div style={styles.emptyIcon}>πŸ’¬</div>\n <h3 style={styles.emptyTitle}>\n {hasAny ? 'Select a conversation' : 'No conversations yet'}\n </h3>\n <p style={styles.emptySubtitle}>\n {hasAny\n ? 'Pick a patient from the list to start collaborating'\n : 'Conversations appear here once you start messaging about a case'}\n </p>\n </div>\n );\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n container: {\n display: 'flex',\n height: '100%',\n width: '100%',\n backgroundColor: COLOR.white,\n fontFamily: FONT_STACK,\n },\n sidebar: {\n width: '320px',\n minWidth: '280px',\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n },\n sidebarCompact: {\n width: '100%',\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n },\n main: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n padding: SPACE.S3,\n backgroundColor: COLOR.neutral100,\n },\n mainCompact: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n backgroundColor: COLOR.neutral100,\n },\n panel: {\n height: '100%',\n width: '100%',\n },\n empty: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: `${SPACE.S12} ${SPACE.S6}`,\n textAlign: 'center',\n },\n emptyIcon: {\n fontSize: FONT_SIZE.xxl,\n marginBottom: SPACE.S3,\n },\n emptyTitle: {\n margin: `0 0 ${SPACE.S2}`,\n fontSize: FONT_SIZE.lg,\n fontWeight: FONT_WEIGHT.semibold,\n color: COLOR.neutral700,\n },\n emptySubtitle: {\n margin: 0,\n fontSize: FONT_SIZE.sm,\n color: COLOR.neutral500,\n maxWidth: '320px',\n },\n};\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { Message } from '../core/types';\nimport { MESSAGES_PAGE_SIZE } from '../core/constants';\n\ninterface UseMessagesOptions {\n conversationId: string | null;\n /** Initial page size (default 30) */\n initialLimit?: number;\n}\n\ninterface UseMessagesReturn {\n messages: Message[];\n isLoading: boolean;\n hasMore: boolean;\n error: string | null;\n loadMore: () => Promise<void>;\n addMessage: (message: Message) => void;\n updateMessageReadBy: (messageId: string, userId: string) => void;\n reset: () => void;\n}\n\n/**\n * Standalone hook for message history management.\n * Use this if you need message data outside of useConversation\n * (e.g. building a completely custom UI).\n */\nexport function useMessages({\n conversationId,\n initialLimit = MESSAGES_PAGE_SIZE,\n}: UseMessagesOptions): UseMessagesReturn {\n const { fetchMessages, config } = useCollab();\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const loadedRef = useRef<string | null>(null);\n\n // Load initial messages when conversation changes\n useEffect(() => {\n if (!conversationId) {\n setMessages([]);\n setHasMore(false);\n loadedRef.current = null;\n return;\n }\n\n if (loadedRef.current === conversationId) return;\n\n let cancelled = false;\n\n const loadInitial = async () => {\n setIsLoading(true);\n setError(null);\n try {\n const initial = await fetchMessages(conversationId, { limit: initialLimit });\n if (cancelled) return;\n setMessages(initial);\n setHasMore(initial.length >= initialLimit);\n loadedRef.current = conversationId;\n } catch (err) {\n if (cancelled) return;\n const msg = err instanceof Error ? err.message : 'Failed to load messages';\n setError(msg);\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load messages',\n details: err,\n });\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n loadInitial();\n\n return () => {\n cancelled = true;\n };\n }, [conversationId, initialLimit, fetchMessages, config]);\n\n const loadMore = useCallback(async () => {\n if (!conversationId || !hasMore || isLoading) return;\n\n const oldestId = messages[0]?.id;\n setIsLoading(true);\n try {\n const older = await fetchMessages(conversationId, {\n limit: initialLimit,\n before: oldestId,\n });\n setMessages((prev) => [...older, ...prev]);\n setHasMore(older.length >= initialLimit);\n } catch (err) {\n config.onError?.({\n code: 'LOAD_ERROR',\n message: 'Failed to load older messages',\n details: err,\n });\n } finally {\n setIsLoading(false);\n }\n }, [conversationId, hasMore, isLoading, messages, initialLimit, fetchMessages, config]);\n\n const addMessage = useCallback((message: Message) => {\n setMessages((prev) => [...prev, message]);\n }, []);\n\n const updateMessageReadBy = useCallback((messageId: string, userId: string) => {\n setMessages((prev) =>\n prev.map((msg) =>\n msg.id === messageId && !(msg.readBy ?? []).includes(userId)\n ? { ...msg, readBy: [...(msg.readBy ?? []), userId] }\n : msg\n )\n );\n }, []);\n\n const reset = useCallback(() => {\n setMessages([]);\n setHasMore(true);\n setError(null);\n loadedRef.current = null;\n }, []);\n\n return {\n messages,\n isLoading,\n hasMore,\n error,\n loadMore,\n addMessage,\n updateMessageReadBy,\n reset,\n };\n}\n","import { useState, useRef, useCallback } from 'react';\nimport { AUDIO_MIME_TYPE } from '../core/constants';\n\ninterface UseAudioRecorderReturn {\n /** Whether the mic is currently recording */\n isRecording: boolean;\n /** Recording duration in seconds (updates every second while recording) */\n duration: number;\n /** Start recording from the microphone */\n start: () => Promise<void>;\n /** Stop recording and return the audio blob */\n stop: () => Promise<{ blob: Blob; duration: number } | null>;\n /** Cancel recording without producing output */\n cancel: () => void;\n /** Whether the browser supports audio recording */\n isSupported: boolean;\n /** Error message if recording fails */\n error: string | null;\n}\n\n/**\n * Wraps the browser MediaRecorder API for voice message recording.\n * Returns a blob suitable for uploading via config.onUploadFile.\n */\nexport function useAudioRecorder(): UseAudioRecorderReturn {\n const [isRecording, setIsRecording] = useState(false);\n const [duration, setDuration] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const chunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const startTimeRef = useRef<number>(0);\n const resolveRef = useRef<((value: { blob: Blob; duration: number } | null) => void) | null>(null);\n\n const isSupported =\n typeof window !== 'undefined' &&\n typeof navigator !== 'undefined' &&\n !!navigator.mediaDevices?.getUserMedia &&\n !!window.MediaRecorder;\n\n const cleanup = useCallback(() => {\n if (timerRef.current) {\n clearInterval(timerRef.current);\n timerRef.current = null;\n }\n\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n\n mediaRecorderRef.current = null;\n chunksRef.current = [];\n setIsRecording(false);\n setDuration(0);\n }, []);\n\n const start = useCallback(async () => {\n if (!isSupported) {\n setError('Audio recording is not supported in this browser');\n return;\n }\n\n try {\n setError(null);\n chunksRef.current = [];\n\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Pick the best supported MIME type\n const mimeType = MediaRecorder.isTypeSupported(AUDIO_MIME_TYPE)\n ? AUDIO_MIME_TYPE\n : MediaRecorder.isTypeSupported('audio/webm')\n ? 'audio/webm'\n : 'audio/mp4';\n\n const recorder = new MediaRecorder(stream, { mimeType });\n mediaRecorderRef.current = recorder;\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunksRef.current.push(event.data);\n }\n };\n\n recorder.onerror = () => {\n setError('Recording failed');\n cleanup();\n resolveRef.current?.(null);\n resolveRef.current = null;\n };\n\n recorder.onstop = () => {\n const finalDuration = Math.round((Date.now() - startTimeRef.current) / 1000);\n const blob = new Blob(chunksRef.current, { type: mimeType });\n\n cleanup();\n resolveRef.current?.({ blob, duration: finalDuration });\n resolveRef.current = null;\n };\n\n recorder.start(250); // collect data every 250ms\n startTimeRef.current = Date.now();\n setIsRecording(true);\n\n // Update duration counter every second\n timerRef.current = setInterval(() => {\n const elapsed = Math.round((Date.now() - startTimeRef.current) / 1000);\n setDuration(elapsed);\n }, 1000);\n } catch (err) {\n if (err instanceof DOMException && err.name === 'NotAllowedError') {\n setError('Microphone access denied. Please allow microphone permissions.');\n } else {\n setError('Failed to start recording');\n }\n cleanup();\n }\n }, [isSupported, cleanup]);\n\n const stop = useCallback(async (): Promise<{ blob: Blob; duration: number } | null> => {\n return new Promise((resolve) => {\n if (!mediaRecorderRef.current || mediaRecorderRef.current.state === 'inactive') {\n resolve(null);\n return;\n }\n\n resolveRef.current = resolve;\n mediaRecorderRef.current.stop();\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {\n // Remove onstop handler to avoid producing output\n mediaRecorderRef.current.onstop = null;\n mediaRecorderRef.current.stop();\n }\n cleanup();\n resolveRef.current?.(null);\n resolveRef.current = null;\n }, [cleanup]);\n\n return {\n isRecording,\n duration,\n start,\n stop,\n cancel,\n isSupported,\n error,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useCollab } from '../context/CollabProvider';\n\ninterface UseUnreadCountReturn {\n /** Total unread messages across all conversations */\n totalUnread: number;\n /** Get unread count for a specific conversation */\n getCountForConversation: (conversationId: string) => number;\n /** Manually clear unread count for a conversation (e.g. when user opens it) */\n clearForConversation: (conversationId: string) => void;\n}\n\n/**\n * Tracks unread message counts.\n * Counts are pushed from the server via the user channel (no polling).\n */\nexport function useUnreadCount(): UseUnreadCountReturn {\n const { socket, totalUnread } = useCollab();\n const [counts, setCounts] = useState<Record<string, number>>({});\n\n useEffect(() => {\n socket.onUnreadCountUpdate((serverCounts) => {\n setCounts(serverCounts);\n });\n }, [socket]);\n\n const getCountForConversation = useCallback(\n (conversationId: string): number => {\n return counts[conversationId] ?? 0;\n },\n [counts]\n );\n\n const clearForConversation = useCallback((conversationId: string) => {\n setCounts((prev) => {\n const next = { ...prev };\n delete next[conversationId];\n return next;\n });\n }, []);\n\n return {\n totalUnread,\n getCountForConversation,\n clearForConversation,\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useCollab } from '../context/CollabProvider';\nimport type { Message } from '../core/types';\n\ninterface UsePinnedMessagesOptions {\n conversationId: string | null;\n /** Initial pinned messages from preview/initial load (avoids extra fetch) */\n initial?: Message[];\n}\n\ninterface UsePinnedMessagesReturn {\n pinnedMessages: Message[];\n isLoading: boolean;\n error: string | null;\n pin: (messageId: string) => Promise<void>;\n unpin: (messageId: string) => Promise<void>;\n /** Handlers to wire to socket pin/unpin events */\n handlePinned: (message: Message) => void;\n handleUnpinned: (messageId: string) => void;\n refresh: () => Promise<void>;\n}\n\n/**\n * Manages pinned messages for a conversation.\n * Backend enforces MAX_PINNED_MESSAGES (3) β€” attempting to pin a 4th returns an error.\n */\nexport function usePinnedMessages({\n conversationId,\n initial = [],\n}: UsePinnedMessagesOptions): UsePinnedMessagesReturn {\n const { pinMessage, unpinMessage, fetchPinnedMessages, config } = useCollab();\n const [pinnedMessages, setPinnedMessages] = useState<Message[]>(initial);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n if (!conversationId) return;\n setIsLoading(true);\n setError(null);\n try {\n const pinned = await fetchPinnedMessages(conversationId);\n setPinnedMessages(pinned);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to load pinned messages';\n setError(msg);\n } finally {\n setIsLoading(false);\n }\n }, [conversationId, fetchPinnedMessages]);\n\n // Only auto-fetch if we don't have initial data\n useEffect(() => {\n if (conversationId && initial.length === 0) {\n refresh();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [conversationId]);\n\n const pin = useCallback(\n async (messageId: string) => {\n if (!conversationId) return;\n setError(null);\n try {\n await pinMessage(conversationId, messageId);\n // Server broadcasts message:pinned β€” handled via handlePinned\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to pin message';\n setError(msg);\n config.onError?.({\n code: 'PIN_ERROR',\n message: msg,\n details: err,\n });\n }\n },\n [conversationId, pinMessage, config]\n );\n\n const unpin = useCallback(\n async (messageId: string) => {\n if (!conversationId) return;\n setError(null);\n try {\n await unpinMessage(conversationId, messageId);\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to unpin message';\n setError(msg);\n config.onError?.({\n code: 'UNPIN_ERROR',\n message: msg,\n details: err,\n });\n }\n },\n [conversationId, unpinMessage, config]\n );\n\n const handlePinned = useCallback((message: Message) => {\n setPinnedMessages((prev) => {\n if (prev.some((m) => m.id === message.id)) return prev;\n return [...prev, message];\n });\n }, []);\n\n const handleUnpinned = useCallback((messageId: string) => {\n setPinnedMessages((prev) => prev.filter((m) => m.id !== messageId));\n }, []);\n\n return {\n pinnedMessages,\n isLoading,\n error,\n pin,\n unpin,\n handlePinned,\n handleUnpinned,\n refresh,\n };\n}\n"]}